Rounding doubles for use in NSString - objective-c

I have a situation where I have lots of different double values, for example 1.00, 0.25 and 2.50. I would like to round these doubles so that they become 1, 0.25 and 2.5; in other words I want to remove any trailing 0's. Is there a way to do this?
At the moment I have been using %.2f, and I'm wondering if I can make use of this but adapt it in some way. Please can someone help me out?

As long as you're talking only about display, this is quite easy. The format specifier you want is %g:
The double argument shall be converted in the style f or e (or in the style F or E in the case of a G conversion specifier), with the precision specifying the number of significant digits [...] Trailing zeros shall be removed from the fractional portion of the result[...]
double twopointfive = 2.500;
double onepointzero = 1.0;
double pointtwofive = .25000000000;
NSLog(#"%g %f", twopointfive, twopointfive);
NSLog(#"%g %f", onepointzero, onepointzero);
NSLog(#"%g %f", pointtwofive, pointtwofive);
2011-12-06 21:27:59.180 TrailingZeroes[39506:903] 2.5 2.500000
2011-12-06 21:27:59.184 TrailingZeroes[39506:903] 1 1.000000
2011-12-06 21:27:59.185 TrailingZeroes[39506:903] 0.25 0.250000
The same format specifier can be used with an NSNumberFormatter, which will also give you some control over significant digits.
The trailing zeroes can't be removed from the way the number is stored in memory, of course.

I believe you want the %g format specifier to redact trailing zeros.

Not really rounding, but have you tried just %f it should only show the number of digits required rather then padding out the number.
My answer above is wrong, %g as others has stated is the right way to go.
The documentation for string formatters should help too. http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265

Here is a list of all the format specifiers that you can use...
%# Object
%d, %i signed int
%u unsigned int
%f float/double
%x, %X hexadecimal int
%o octal int
%zu size_t
%p pointer
%e float/double (in scientific notation)
%g float/double (as %f or %e, depending on value)
%s C string (bytes)
%S C string (unichar)
%.*s Pascal string (requires two arguments, pass pstr[0] as the first, pstr+1 as the second)
%c character
%C unichar
%lld long long
%llu unsigned long long
%Lf long double

Related

How to print uint64_t properly in D language (dtrace)

I'm trying to printf some Solaris kernel level information with the type of uint64_t (e.g. timestamp) using a DTrace script. How I can print uint64_t safely and precisely in my DTrace code.
I know the proper way of printing uint64_t in C is:
#define __STDC_FORMAT_MACROS
#include <sys/inttypes.h> //sys: Kernel level
uint64_t timestamp;
printf("%"PRIu64"\n", timestamp);
What's an equivalent in DTrace D? (%d and `%llu are imprecise and dangerous).
NOTE Not to be confused with other programming languages named "D" (a C++-like programming language developed by Walter Bright).
According to DTrace Wiki: Output Formatting:
The D compiler does not require the use of size prefixes with printf format conversions.
The C printf routine requires that you indicate the size of arguments by adding prefixes such as %ld for long or %lld for long long.
The D compiler knows the size and type of your arguments, so these prefixes are not required in your D printf statements.
Moreover, the %d and %i formats in D will handle either signed or unsigned ints, so you can use any of %d, %i, or %u to print an unsigned integer value in base 10, all with the same results.
The OP asked in a comment about the %Y format. This can be used for a uint64_t value that contains the number of nanoseconds since the Jan 1 1970 epoch, e.g. the built-in walltimestamp variable. (timestamp and vtimestamp are not counted from that epoch.)
The uint64_t argument is interpreted to be the number of nanoseconds since 00:00 Universal Coordinated Time, January 1, 1970, and is printed in the following cftime(3C) form: "%Y %a %b %e %T %Z."

Objective-C float being limited to 6 decimal places? [duplicate]

This question already has answers here:
What's the difference between float and double?
(3 answers)
Closed 8 years ago.
I have an Objective-C project that needs to display numbers like 0.00000217, and very small numbers like that. Problem is, Objective-C is rounding this to the 6th decimal place so it displays as 0.000002. Is there a type to display more decimal places? My code:
float floatValueOfSmallNumber = [value floatValue];
[theLabel setText:[NSString stringWithFormat:#"%f", floatValueOfSmallNumber]];
Thanks!
While a float only has ~7 significant decimal digits, that's not the problem you are running up against here; 0.00000217 has only three significant digits, after all.
You are using the %f format specifier which is inherited from C and defined thus (7.21.6 Formatted input/output functions):
A double argument representing a floating-point number is converted to decimal notation in the style [−]ddd.ddd, where the number of digits after the decimal-point character is equal to the precision specification. If the precision is missing, it is taken as 6; if the precision is zero and the # flag is not specified, no decimal-point character appears. If a decimal-point character appears, at least one digit appears before it. The value is rounded to the appropriate number of digits.
Using double won't change this; instead, you need to change your format specifier. You can use %e or %g if you don't mind scientific notation, but another alternative would be to use a precision specifier: %.10f, for example, will print ten decimal digits.

Scientific notation with three significant figures

Is there a way to use scientific notation in objective c and have it display three significant digits only? What I am current using is:
string = [NSString stringWithFormat:#"%e", floatNumber];
// floatNumber = 100000; string = 1.000000e+06
I just want string = 1.00e+06
Use the format specifier ".2" as follows:
string = [NSString stringWithFormat:#"%.2e", floatNumber];
From apple's documentation:
The format specifiers supported by the NSString formatting methods and CFString formatting functions follow the IEEE printf specification...
And from the IEEE printf specification, if you read under the Description section, you will find:
e, E
The double argument shall be converted in the style "[-]d.ddde±dd", where there is one digit before the radix character (which is non-zero if the argument is non-zero) and the number of digits after it is equal to the precision; if the precision is missing, it shall be taken as 6; if the precision is zero and no '#' flag is present, no radix character shall appear. The low-order digit shall be rounded in an implementation-defined manner. The E conversion specifier shall produce a number with 'E' instead of 'e' introducing the exponent. The exponent shall always contain at least two digits. If the value is zero, the exponent shall be zero.

Convert double decimal to Hex, Binary and Octal strings

Is there a custom or standard library that I can use with objective c to convert a decimal floating point value into Hexadecimal, Binary and Octal NSStrings?
I've been looking around a lot but can only find how to convert the other direction (from everything else into decimal), by using: double result = (double)strtoll(myHexString.UTF8String, NULL,16)
As for octal and hex, you can exploit the fact that you can format numbers in hex and octal using the %x and %o specifiers:
NSString* str=[NSString stringWithFormat: #"Hex: %x Octal: %o",14,14];
But this only for the integral part, so you can use integers.If you want also the decimal part, to obtain fixed points you need to implement the algorithm, same for binary.
In order to complement the previous answer, the format specifier %x allows to treat integer value only.
If you get a decimal value greater than the max integer value you can use long long to cast your double value by this way: NSString * hexString = [NSString stringWithFormat:#"%llx", (long long)doubleValue];

Make a two-digit string from a single-digit integer

How can I have a two-digit integer in a a string, even if the integer is less than 10?
[NSString stringWithFormat:#"%d", 1] //should be #"01"
I believe that the stringWithFormat specifiers are the standard IEEE printf specifiers. Have you tried
[NSString stringWithFormat:#"%02d", 1];
Use the format string %02d. This specifies to format an integer with a minimum field-width of 2 characters and to pad the formatted values with 0 to meet that width. See man fprintf for all the gory details of format specifiers.
If you are formatting numbers for presentation to the user, though, you should really be using NSNumberFormatter. Different locales have wildly different expectations about how numbers should be formatted.
[NSString stringWithFormat:#"%00.02d", intValue]
This help me to convert 1 to 01.