Is there a string formatter available for double? - objective-c

i'm looking for a way to represent a double value in a NSString meeting the following format requirements:
1.) no trailing zeros: x = 0.5000000 -> #"0.5"
2.) at least on decimal: x = 45 -> #"45.0"
3.) maximum 8 decimal characters (last one rounded): x = 0.000000005 -> #"0.00000001"
I tried with #"%.8f", #"%g" or #"%.8g" but all fail for at least one of the requirements.
I think I could do with #"%.8f" and then loop the characters of the string beginning with the last character of string to the front deleting the "0" characters,
Or start with a "%.8g" and append a ".0" if the string does not contain a decimal point.
Is there any smarter solution available?

You can do this with a number formatter, but you need to create an NSNumber with your double first:
NSNumber *halfNumber = [NSNumber numberWithDouble:0.5000000];
NSNumber *wholeNumber = [NSNumber numberWithDouble:45];
NSNumber *longNumber = [NSNumber numberWithDouble:0.000000005];
NSNumberFormatter *formatter = [NSNumberFormatter new];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
formatter.roundingMode = NSNumberFormatterRoundHalfUp;
formatter.minimumFractionDigits = 1;
formatter.maximumFractionDigits = 8;
NSString *halfString = [formatter stringFromNumber:halfNumber];
NSString *wholeString = [formatter stringFromNumber:wholeNumber];
NSString *longString = [formatter stringFromNumber:longNumber];
NSLog(#"%#", halfString);
NSLog(#"%#", wholeString);
NSLog(#"%#", longString);
// Output is:
// 2012-11-12 04:22:41.181 Testing App[48069:fb03] 0.5
// 2012-11-12 04:22:41.182 Testing App[48069:fb03] 45.0
// 2012-11-12 04:22:41.183 Testing App[48069:fb03] 0.00000001

Related

Objective C remove trailing zeros after decimal place

I am trying to get number in 2 decimal places with trailing zeros.
e.g
11.633-> 11.63
11.630-> 11.63
11.60-> 11.6
11-> 11
12928.98-> 12928.98
for this I written below line
#define kFloatFormat2(x) [NSString stringWithFormat:#"%g", [[NSString stringWithFormat:#"%.2f", x] floatValue]]
NSNumber *number1 = [NSNumber numberWithDouble:12928.98];
NSLog(#"number1:%#", number1);
NSString *string1 = kFloatFormat2([number1 floatValue]);
NSLog(#"string1:%#", string1);
the output of above prints
number1:12928.98
string1:12929
Why it prints 12929 value for string1
I want it as 12928.98.
Have you tried using a number formatter?
NSNumberFormatter *formatter = [[NSNumberFormatter alloc]init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setUsesGroupingSeparator:NO];
[formatter setMaximumFractionDigits:fractionDigits];
[formatter setMinimumFractionDigits:fractionDigits];
Now do something like
NSNumber *x = #23423;
NSString *value = [formatter stringFromNumber:x];
NSLog(#"number = %#, value);
You macro makes no sense. Just make it:
#define kFloatFormat2(x) [NSString stringWithFormat:#"%.2f", [x floatValue]]
where x is an NSNumber. And then you would call it like this:
NSString *string1 = kFloatFormat2(number1);
Or just do this:
double x = 12928.98;
NSLog(#"number = %.2f", x);

How to display leading zero in double

I need to make NSNumber to display only 4 decimal points. This part of code is works, but it outputs result without leading zero.
double resultRoundToDecimal = [result doubleValue];
NSNumberFormatter *resultFormatter = [[NSNumberFormatter alloc] init];
[resultFormatter setRoundingMode:NSNumberFormatterRoundHalfUp];
[resultFormatter setMaximumFractionDigits:4];
resultData = [resultFormatter stringFromNumber:[NSNumber numberWithDouble:resultRoundToDecimal]];
For example:
1/3 = .3333
I want:
1/3 = 0.3333
How I can to do this?
You could choose to use string formatter too, like below
float val=1./3;
NSString *resultData=[NSString stringWithFormat:#"%0.4f",val];
NSLog(#"Result = %#",resultData);
Prepend a 0 or use number formatter.
NSString *printStr = #"0";
printStr = [NSString stringByAppendingString: resultData];
Otherwise, you could use a number formatter or something similar. If your just outputting a string why not do that?
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNumberFormatter_Class/Reference/Reference.html

NSNumberFormatter leading 0's and decimals

Is there any way to format an NSNumber with leading 0's and decimals? For example, I need to have the ability to write 4.5 as well as 000. Currently I have it where it will allow decimals, but not leading 0's.
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
f.numberStyle = NSNumberFormatterNoStyle;
NSString *myString = [f numberFromString:#"4.5"];
NSLog(#"myString: %#",myString);
NSString *myOtherString = [f numberFromString:#"000"];
NSLog(#"myOtherString:%#",myOtherString);
The output from above would be: 'myString:4.5' and 'myOtherString:0'. I need to be able to do both '4.5' and '000' as output.
I have looked at Apple's "Data Formatting Guide" without much success.
Note that [f numberFromString:#"4.5"] returns an NSNumber* not a NSString*
You want something like this:
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
f.numberStyle = NSNumberFormatterNoStyle;
NSNumber *myNumber;
NSString *myString;
myNumber = [f numberFromString:#"4.5"];
[f setNumberStyle:kCFNumberFormatterDecimalStyle];
myString = [f stringFromNumber:myNumber];
NSLog(#"myString: %#",myString);
myNumber = [f numberFromString:#"000"]; // Note that the extra zeros are useless
[f setFormatWidth:3];
[f setPaddingCharacter:#"0"];
myString = [f stringFromNumber:myNumber];
NSLog(#"myString: %#",myString);
NSLog output:
myString: 4.5
myString: 000
If you don't have strings to start with just create number like:
myNumber = [NSNumber numberWithFloat:4.5];
myNumber = [NSNumber numberWithInt:0];
Or just use standard formatting:
myString = [NSString stringWithFormat:#"%.1f", [myNumber floatValue]];
myString = [NSString stringWithFormat:#"%03d", [myNumber intValue]];
Or if you don't need an NSNumber representation just use standard formatting :
myString = [NSString stringWithFormat:#"%.1f", 4.5];
myString = [NSString stringWithFormat:#"%03d", 0];
You could try something like:
NSString *myString = [NSString stringWithFormat:#"%03f", [myNSNumber floatValue]];
This, following the printf format, will print your number forcing at least 3 digits to be printed and padding with '0's any empty space.
How about this as a variation on theme for the 000's
NSNumber *myNumber;
NSString *myString =#"000" ;
NSString * myStringResult;
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
f.numberStyle = NSNumberFormatterNoStyle;
[f setHasThousandSeparators:FALSE]; //-- remove seperator
[f setMinimumIntegerDigits:[myString length ]]; //-- set minimum number of digits to display using the string length.
myNumber = [f numberFromString:myString];
myStringResult = [f stringFromNumber:myNumber];
NSLog(#"myStringResult: %#",myStringResult);
Since this is asked often and Apple's docs suck, this is the answer that people will be looking for. The link below has two solutions. One using NSString stringWithFormat: and the other using NSNumberFormatter.
https://stackoverflow.com/a/11131497/1058199

Why aren't the decimals printed to the string?

In order to get a string with 2 decimals value I've tried:
[[NSString stringWithFormat:#"%.2f",[[self CurrentValue] doubleValue]]]
this
[self CurrentValue] stringValue]
and this:
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterCurrencyStyle;
NSString *string = [formatter stringFromNumber:[self CurrentValue]];
[formatter release];
But it doesn't work. THe original number is a float = 22, and I always get a string "22", and not "22.00".
Thanks
I ran a few test scenarios and hopefully this can help you get to the bottom of it. The formatter is ideal if you are doing a currency, otherwise string1 is ideal. To work from this example you can set number up - NSNumber * number = [self CurrentValue];
NSNumber * number = [NSNumber numberWithInt:22];
NSString * string1 = [NSString stringWithFormat:#"%.2f",[number doubleValue]];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterCurrencyStyle;
NSString *string2 = [formatter stringFromNumber:number];
[formatter release];
NSLog(#"string 1 %#\nstring 2 %#\nstring 3 %#", string1, string2, [number stringValue]);
//output
string 1 22.00
string 2 $22.00
string 3 22
// top code with NSNumber * number = [NSNumber numberWithFloat:22];
string 1 22.00
string 2 $22.00
string 3 22
// top code with NSNumber * number = [NSNumber numberWithFloat:22.0];
string 1 22.00
string 2 $22.00
string 3 22
Summary:
The way the number is created is not significant here to the output if it is truly an int (floats with such as 4.20 will work as expected in every case, but every int value 22,22.0,22.000 gets treated the same by all 3 ways of creating a number. So choose the format you like best and implement that.
Seems you have extra [] around. You can try
[NSString stringWithFormat:#"%.2f",[[self CurrentValue] floatValue]]
or
[NSString stringWithFormat:#"%.2lf",[[self CurrentValue] doubleValue]] both are good to go.
It actually much simpler.
You said that "The original number is a float = 22". Now, remember that obj-c runtime class may differ from declared one. And when you instantiate your float variable with actually integer value - it is an integer one at runtime! You should change it to one of the following:float someFloatValue = 22f;float someFloatValue = 22.0;float someFloatValue = (float)22; (not sure about that one thought)
Happy coding...

How to add commas to number every 3 digits in Objective C?

If I have a number int aNum = 2000000 how do I format this so that I can display it as the NSString 2,000,000?
Use NSNumberFormatter.
Specifically:
NSNumberFormatter *formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle]; // this line is important!
NSString *formatted = [formatter stringFromNumber:[NSNumber numberWithInteger:2000000]];
[formatter release];
By default NSNumberFormatter uses the current locale so the grouping separators are set to their correct values by default. The key thing is to remember to set a number style.
Don't do your own number formatting. You will almost certainly not get all the edge cases right or correctly handle all possible locales. Use the NSNumberFormatter for formatting numeric data to a localized string representation.
You would use the NSNumberFormatter instance method -setGroupingSeparator: to set the grouping separator to #"," (or better yet [[NSLocale currentLocale] objectForKey:NSLocaleGroupingSeparator]; thanks #ntesler) and -setGroupingSize: to put a grouping separator every 3 digits.
There's a static method on NSNumberFormatter that does just what you need:
int aNum = 2000000;
NSString *display = [NSNumberFormatter localizedStringFromNumber:#(aNum)
numberStyle:NSNumberFormatterDecimalStyle];
This way is a little more succinct than creating a new NSNumberFormatter if you don't need to do any additional configuration of the formatter.
Even easier:
NSNumber *someNumber = #(1234567890);
NSString *modelNumberString = [NSString localizedStringWithFormat:#"%#", someNumber];
NSLog(#"Number with commas: %#", modelNumberString);
coworker just taught me this today. #amazing
Think some as i will get this post looking for sample.
So if you are working with number make attention on next params:
setNumberStyle:NSNumberFormatterCurrencyStyle // if you are working with currency
It could be also
setNumberStyle:NSNumberFormatterDecimalStyle
All code is For ARC.
If you are working with Integer and need to get result such as 200,000
int value = 200000;
NSNumberFormatter * formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSString * newString = [formatter stringFromNumber:[NSNumber numberWithInteger:value]];
If you are working with Float and need to get result such as 200,000.00
float value = 200000;
NSNumberFormatter * formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMaximumFractionDigits:2]; // Set this if you need 2 digits
NSString * newString = [formatter stringFromNumber:[NSNumber numberWithFloat:value]];
EDIT
To have ability to use different digital separators use NSLocale.
Add to code where NSLocale is specified on Locale Identifier:
[formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"de_DE"]];
or use current local:
[formatter setLocale:[NSLocale currentLocale]];
Swift version
let formatter = NSNumberFormatter()
formatter.numberStyle = .DecimalStyle
formatter.maximumFractionDigits = decimalPlaces
let result = formatter.stringFromNumber(NSNumber(double: 8.0))
By http://ios.eezytutorials.com
An easy solution could be this. My answer is almost same like #Nazir's answer but with a small trick.
double current_balance = 2000000.00;
NSNumberFormatter * formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
//[formatter setNumberStyle:NSNumberFormatterCurrencyStyle]; //if you want for currency with $ sign
[formatter setMinimumFractionDigits:2]; // Set this if you need 2 digits
[formatter setMaximumFractionDigits:2]; // Set this if you need 2 digits
NSString * currency_format = [NSString stringWithFormat:#"%#", [formatter stringFromNumber:[NSNumber numberWithDouble:current_balance]]];
For Swift 4.0
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
let result = formatter.string(from: NSNumber(value: 123456))
For those who need to do it with strings of numbers and not just integers (I.e. Big Numbers) I made the following macro:
#define addCommas(__string) (\
(^NSString *(void){\
NSString *__numberString = __string;\
NSString *__integerPortion = __numberString;\
NSString *__decimalPortion = #"";\
if ([__string containsString:#"."]) {\
__integerPortion = [__numberString componentsSeparatedByString:#"."][0];\
__decimalPortion = st(#".%#", [__numberString componentsSeparatedByString:#"."][1]);\
}\
int __i = (int)__integerPortion.length-3;\
while (__i > 0) {\
__integerPortion = st(#"%#,%#", substringInRange(__integerPortion, 0, __i), substringInRange(__integerPortion, __i, (int)__integerPortion.length));\
__i -= 3;\
}\
__numberString = st(#"%#%#", __integerPortion, __decimalPortion);\
return __numberString;\
})()\
)