Output A Float Without Zero Before Decimal Point - objective-c

I'm wondering how a float that has a zero followed by a decimal followed by numbers like this:
0.45
...to ditch the zero that's in front of the decimal point like this:
.45
within a NSString using the [NSString stringWithFormat:] method using Objective C.

You can't directly eliminate the leading 0 when formatting a floating point value using stringWithFormat: and %f. You will have to remove it yourself from the result:
NSString *result = [NSString stringWithFormat:#"%.2f", 0.45];
if ([result hasPrefix:#"0."]) {
result = [result substringFromIndex:1];
}
But a better solution is to use NSNumberFormatter. Set minimumIntegerDigits to 0 to avoid the leading 0.
NSNumberFormatter *fmt = [[NSNumberFormatter alloc] init];
fmt.numberStyle = NSNumberFormatterDecimalStyle;
fmt.minimumInterDigits = 0;
NSString *result = [fmt stringFromNumber:#(0.45)];
This has the advantage of formatting the result properly for the user's locale (other than removing the leading 0).
It may best to avoid removing the leading 0. The output may be confusing to users.

Related

Objective-C: Double to NSString with x-many decimals

I know that I can cast a double to a NSString with a specific amount of decimals like so:
double myDouble = 123.456789;
NSString *myString = [NSString stringWithFormat:#"%.4g", myDouble];
But how can I replace the number "4" in this example with a int variable?
Something like this doesn't work:
double myDouble = 123.456789;
int precision = 4;
NSString *myString = [NSString stringWithFormat:#"%.%dg", myDouble, precision];
Consider using NSNumberFormatter:
double myDouble = 123.456789;
int precision = 4;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.minimumFractionDigits = precision;
formatter.maximumFractionDigits = precision;
NSString *myString = [formatter stringFromNumber:#(myDouble)];
Or, if you want this in scientific notation, you can alternatively specify something like:
formatter.numberStyle = NSNumberFormatterScientificStyle;
formatter.usesSignificantDigits = YES;
formatter.minimumSignificantDigits = precision;
formatter.maximumSignificantDigits = precision;
It just depends upon what precisely you're looking for.
This also has the virtue of also honoring the user's regional settings (e.g. if in Germany, the decimal separator is a comma, not a period).
If you need to force the locale setting (e.g. this is for creating something that will be exchanged with a web service that expects the data in a specified format), you can set the formatter's locale (e.g. [NSLocale localeWithLocaleIdentifier:#"en_US"]). But when presenting results in the user interface, you always want to honor the device's locale settings.
You can use asterisk in place of optional width and precision specifiers. And set them as arguments
double myDouble = 123.456789;
int width = 10;
int precision = 6;
NSString *s = [NSString stringWithFormat:#"%*.*g", width, precision, myDouble];
If you follow the links in the documentation for stringWithFormat you will discover the IEEE printf specification which describes the formats supported. That tells you that a field width or precision can be an * to indicate the actual value is supplied an an int argument, so what you want is:
NSString *myString = [NSString stringWithFormat:#"%.*g", intPrecision, myDouble];
double myDouble = 123.456789;
int precision = 4;
NSString *myString = [NSString stringWithFormat:#"%.*f", precision, myDouble];
NSLog(#"myString: '%#'", myString);
NSLog output:
myString: '123.4567'
This is by no means an optimal way of doing it, but it is a way.
You can do it in multiple steps
NSString *val = [NSString stringWithFormat: #"%d", 4];
NSString *head = [#"%." stringByAppendingString: val];
NSString *format = [head stringByAppendingString: #"g"];
NSString *result = [NSString stringWithFormat: format, 123.456789];
Or if you're really adventurous (for the sake of readability, don't EVER do this):
NSString *result = [NSString stringWithFormat: [[#"%." stringByAppendingString: [NSString stringWithFormat: #"%d", 4]] stringByAppendingString: #"g"], 123.456789];

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

Format values from a NSArray

I have a NSArray containing several strings that look like this: "291839.0930820"
I would like to format those values in the array so that they show up in my detailTextLabel of a UITableView with only 2 decimals: "291,839.09"
How can I accomplish this?
To properly format numbers so the numbers appear correctly for a given user's domain is to use NSNumberFormatter. You should never usevstringWithFormat: for such purposes.
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]:
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMaximumFractionDigits:2];
NSNumber *val = array[indexPath.row];
NSString *text = [formatter stringFromNumber:val];
Update:
I'm getting the feeling from Juan that the array doesn't actually contain NSNumber objects for the numbers but it actually contains NSString representations of the numbers. If this is the case, then one line in my answer needs to be changed. Change:
NSNumber *val = array[indexPath.row];
to:
NSNumber *val = #([array[indexPath.row] doubleValue]);
This will get the NSString from the array, then get the string's value as a double, and finally wrap the double in an NSNumber.
You could try something like this if your array has float values
cell.detailTextLabel.text=[NSString stringWithFormat:#"%.02f", [[array objectAtIndex:index]floatValue]];
lets say your value is double value = 291839.0930820;
You can construct a string like this
NSString *formattedValue = [NSString stringWithFormat:#"%0.2f",value];
assign this formattedValue to your textfield/label.
cell.textLabel.text = formattedValue;

How to leave a set number of spaces in NSString?

I have separate text objects for the unchanging portion (i.e. "Bonus Score: (+7%)") and the changing portion (e.g. "247,890"). Since they're separate, I want to leave space in the unchanging portion to display the number.
What I first tried was:
NSString* numberString = #"247,890";
NSString* blankScore = [#"" stringByPaddingToLength:[numberString length] withString: #" " startingAtIndex:0];
NSString* baseDisplay = [NSString stringWithFormat:#"BONUS SCORE: %# (+7%%)", blankScore];
'blankScore' was the correct length, but the resulting baseDisplay seemed to trim the spaces around where blankScore would be, making it too small of a space for the displayed number.
Next I tried another way of creating blankScore:
NSString* blankScore = [numberString stringByReplacingCharactersInRange:NSMakeRange(0, [numberString length]) withString:#" "];
But this returned a blankScore of length 1.
Am I understanding these NSString methods incorrectly? I checked the docs, and it seems like my understanding of these methods aligns with what's written there, but I still don't understand why I can't get my baseDisplay to have the correct number of spaces.
Have you printed blankScore on the console using NSLog? Actually your string is correct, but the output is trimmed at end of lines - this is why you see it as described.
#H2CO3 is on to the right solution. You should be using:
NSString *baseDisplay = [NSString stringWithFormat:#"BONUS SCORE: %# (+7%%)", numberString];
To make this work even better, you may want to consider an NSNumberFormatter to correctly format the changing part before inserting it into the baseDisplay object. Something like this:
NSNumber *changingNumber = [NSNumber numberWithDouble:247890];
NSNumberFormatter *correctFormat = [[NSNumberFormatter alloc] init];
[correctFormat setNumberStyle:NSNumberFormatterDecimalStyle];
[correctFormat setHasThousandSeparators:YES];
[correctFormat setUsesGroupingSeparator:YES];
NSString *numberString = [correctFormat stringFromNumber:changingNumber];
NSString *baseDisplay = [NSString stringWithFormat:#"BONUS SCORE: %# (+7%%)", numberString];
This way no matter what number you throw at it, it will correctly display "1,234,456" or "34,567", whatever.
EDIT:
Based on the comments to my answer you will need to use:
stringByPaddingToLength:withString:startingAtIndex:
It should look something like this:
NSString *templateString = #"BONUS SCORE:";
NSString *templateString2 = #"(+7%%)";
NSUInteger baseStringLength = [templateString length] + [numberString length];
NSString *spacedString = [templateString stringByPaddingToLength:baseStringLength withString:#" " startingAtIndex:0];
NSString *baseDisplay = [NSString stringWithFormat:#"%#%#", spacedString, templateString2];

How to convert NSString to NSInteger in iPhone application?

NSString * addString=[arrayyyy componentsJoinedByString:#","];
NSLog(#"add string is: %#",addString);// result is: 45,1
Now I want to convert above string into integer.
I have tried this:
NSInteger myInt=[addString intValue];
//NSLog(#"myInt is: %d",myInt);// result is: 45
If you expected 45.1 then there are two things wrong :
45.1 is not an integer. You would have to use floatValue to read the value.
45,1 (notice the comma) is not a valid float number. While 45,1 is valid in some locale (i.e. in french its 1 000,25 instead of 1,000.25) you would have to convert the string with an NSNumberFormatter before reading the floatValue.
.
// Can't compile and verify this right now, so please bear with me.
NSString *str = #"45,1";
NSNumberFormatter *formatter = [[[NSNumberFormatter alloc] init] autorelease];
NSLocale *locale = [[[NSLocale alloc] initWithLocaleIdentifier:#"fr_FR"] autorelease]; // lets say French from France
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setLocale:locale];
float value = [[formatter numberFromString:str] floatValue]; // value = 45.1
Try out NSExpression which works with mathematical symbols too (i.e. +, -, /, *):
NSNumber *numberValue = [[NSExpression expressionWithFormat:inputString] expressionValueWithObject:nil context:nil];
// do something with numberValue
From reading the question a lot, I think I may understand what you want.
The starting point seems to be:
NSLog(#"add string is: %#",addString);// result is: 45,1
And the current ending point is:
NSLog(#"myInt is: %d",myInt);// result is: 45
But it seems that you still want to print out 45,1
My guess on this is that you have an array of 2 strings [#"45",#"1"] called arrayyyy and you want to print out both values as integers. If this is so then what I think you want is:
NSInteger myInt1 = [[arrayyyy objectAtIndex:0] intValue];
NSInteger myInt2 = [[arrayyyy objectAtIndex:1] intValue];
NSLog(#"add string is: %d,%d",myInt1,myInt2);
Note This will crash horribly with an NSRangeException if there are not at least two strings in the array. So at the very least you should do:
NSInteger myInt1 = -1;
NSInteger myInt2 = -1;
if ([arrayyyy length] >0) myInt1 = [[arrayyyy objectAtIndex:0] intValue];
if ([arrayyyy length] >1) myInt2 = [[arrayyyy objectAtIndex:1] intValue];
NSLog(#"add string is: %d,%d",myInt1,myInt2);
But even this is bad as it assumes that the guard value of -1 will not be present in the actual data.