Converting NSString number to float - ios

I am having difficulties converting NSString's that have numbers into floats or something more useful.
I have tried the following code:
NSString *mystring = #"123"
int currentBidAmount = [myString integerValue];
No problem there.
Then float
NSString *mystring = #"123.95"
float currentBidAmount = [myString floatValue];
Again, no problem
However when myString has three decimals - I get an inaccurate number. For Example:
NSString *mystring = #"1.123.95"
float currentBidAmount = [myString floatValue];
It prints out: 1
Can someone tell me what I am doing wrong here?
The goal is to have two NSStrings - get their values and add them up for a total amount. So I need more accuracy than just I am getting now.

While you can get an NSString integer or floatValue you should use NSNumberFormatterfor that. Why? The decimal and grouping separator varies between countries and the floatValue code does only account for . as decimal separator. So users with a locale using a , are doomed.
How to:
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
float myFloat = [numberFormatter numberFromString:myString].floatValue;
Read up on various settings here: https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/classes/NSNumberFormatter_Class/Reference/Reference.html

you can't put two commas for a float value
this code works fins:
NSString *example = #"13124.4153";
float floatValue = [example floatValue];
NSLog(#"value = %f", floatValue);

Thanks for the help guys. I managed to solve the problem. The issue was the grouping separator. It separated by leaving a space. So this is why I had inaccurate numbers. Now, since I needed all my numbers to stay in this format but change when I was doing calculations (Adding sums together - I wrote a class method that looks like this:
(NSString *)getDisplayAmountStringWithValue: (NSString *)value Currency: (NSString *)currency
{
NSDecimalNumber *decimalValue = [NSDecimalNumber decimalNumberWithString:[value stringByReplacingOccurrencesOfString:#"," withString:#""]];
if ([decimalValue isEqualToNumber:[NSDecimalNumber notANumber]]){
decimalValue = [NSDecimalNumber decimalNumberWithString:#"0"];
}
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setGroupingSeparator:#" "];
[formatter setDecimalSeparator:#"."];
[formatter setMaximumFractionDigits:2];
[formatter setMinimumFractionDigits:2];
if ([currency length] > 0){
[formatter setPositivePrefix:[NSString stringWithFormat:#"%#", currency]];
[formatter setNegativePrefix:[NSString stringWithFormat:#"%#-", currency]];
}else {
[formatter setGroupingSeparator:#""];
}
NSString *newNumberString = [formatter stringFromNumber:decimalValue];
return newNumberString;
}
Notice the if statement. I simply remove the space if I don't supply a currency (Which is not needed when adding sums together) - this along with my existing code, works perfectly.
Thanks for all the tips.

Related

Convert numbers to currency

I have number 36381129. I need number 36.381,129
I tried this code, but it doesn't work.
int number = 36381129;
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle: NSNumberFormatterCurrencyStyle];
NSString *numberAsString = [numberFormatter stringFromNumber: [NSNumber numberWithInt:number]];
I give this number.
36.381.129,00 $
I think this is BRAZILIAN REAL CURRENCY Format. You have to call this method with your price in float value, and this method returns your string into your format. Like if we pass 123456789, then it will return 123,456,789.00.
//Convert Price to Your Price Format
+(NSString*)convertFormat:(float)value{
NSString * convertedString = [NSString stringWithFormat:#"%.2f", value];
NSString * leftPart;
NSString * rightPart;
if (([convertedString rangeOfString:#"."].location != NSNotFound)) {
rightPart = [[convertedString componentsSeparatedByString:#"."] objectAtIndex:1];
leftPart = [[convertedString componentsSeparatedByString:#"."] objectAtIndex:0];
}
//NSLog(#"%d",[leftPart length]);
NSMutableString *mu = [NSMutableString stringWithString:leftPart];
if ([mu length] > 3) {
[mu insertString:#"." atIndex:[mu length] - 3];
//NSLog(#"String is %# and length is %d", mu, [mu length]);
}
for (int i=7; i<[mu length]; i=i+4) {
[mu insertString:#"." atIndex:[mu length] - i];
//NSLog(#"%d",mu.length);
}
convertedString = [[mu stringByAppendingString:#","] stringByAppendingString:rightPart];
return convertedString;
}
For more details, refer this blog.
Hope, this is what you're looking for. Any concern get back to me.
Welcome to SO. Your question is pretty vague.
Currency formats depend on the user's locale. It's generally better to either use the default locale of the device, or set a locale, and then let the currency formatter create that string that's appropriate for that locale.
If you set up a hard-coded currency format then it will be wrong for some users. (For example in the US we use a "." as a decimal separator and commas as a grouping symbol. In most of Europe they use a comma as a decimal separator and the period as a grouping symbol. Some countries put the currency symbol at the end of a currency amount, and others put it at the beginning.)
You can use this code:
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSString *groupingSeparator = [[NSLocale currentLocale] objectForKey:NSLocaleGroupingSeparator];
[formatter setGroupingSeparator:groupingSeparator];
[formatter setGroupingSize:3];
[formatter setAlwaysShowsDecimalSeparator:NO];
[formatter setUsesGroupingSeparator:YES];
and use it this way:
NSString *formattedString = [formatter stringFromNumber:[NSNumber numberWithFloat:rev];
This is a generic solution and will work for any country according to their grouping separator
Taken from: https://stackoverflow.com/a/5407103/2082569

Objective C, Trim a float

I have float like 3500,435232123. All I want to know if exists (in Objective C) a function that let me keep just the last 4 digits in my case is 2123.
You can use NSNumberFormatter
NSNumberFormatter *format = [[NSNumberFormatter alloc]init];
[format setNumberStyle:NSNumberFormatterDecimalStyle];
[format setRoundingMode:NSNumberFormatterRoundHalfUp];
[format setMaximumFractionDigits:4];
[format setMinimumFractionDigits:4];
string = [NSString stringWithFormat:#"%#",[format stringFromNumber:[NSNumber numberWithFloat:65.50055]] ;
Or simply
NSString *string = [NSString stringWithFormat:#"%.04f", floatValue];
If you want only last four digits, convert the float to a string
NSString *string = [NSString stringWithFormat:#"%f", floatValue];
and get the last four characters
NSString *lastFour = [string substringFromIndex: [string length] - 4];
It you want to get the decimal part, you can do x - floor(x). For instance:
float x = 3500,435232123;
NSString *string = [NSString stringWithFormat:#"%.04f", x - floor(x)];
And to get 4 decimal digits do what Fawad Masud says.
No there is no such function, as far as i know. But here is a way to achieve exactly what you want.
First you have to round it to four digits after point:
NSString *exampleString = [NSString stringWithFormat:#"%.04f", valueToRound];
Then you get the location for the comma inside the exampleString:
NSRange commaRange = [valueString rangeOfString:#","];
Finally you create the finalString with the values from that NSRange. The substring starts at commaRange.location+commaRange.lengthbecause thats the index directly after the comma.
NSString *finalString = [valueString substringWithRange:NSMakeRange(commaRange.location+commaRange.length,valueString.length-commaRange.location-commaRange.length)];
Hope that helps you.
I think is no predefined function for that.
and the solution i thought of is:
float floatNum = 3500.435232123;
converting float number to string and trim/substring the string, like for example:
NSString *stringFloat = [NSString stringWithFormat:#"%f", floatNum];
NSString *newString = [stringFloat substringWithRange:NSMakeRange(stringFloat.length - 4, stringFloat.length)];
NSLog(#"%#", newString);
another is something like:
NSString *stringFloat = [NSString stringWithFormat:#"%f", floatNum];
//separates the floating number to
arr[0] = whole number
arr[1] = decimals
NSArray *arr=[str componentsSeparatedByString:#"."];
since you just want to work on the decimal, i think arr[1] is what you need..
NSString *stringDecimals = (NSString *)arr[1];
if ( stringDecimals.length > 4) //check the length of the decimals then cut if exceeds 4 character..
{
stringDecimals = [stringDecimals substringWithRange:NSMakeRange(stringDecimals.length - 4, stringDecimals.length)];
}
NSLog(#"stringDecimals: %#", stringDecimals);

NSNumber numberFromString not placed decimals

I am trying to convert NSString to NSNumber and it seems to create a decimal point issue here.
NSString *str = #"515.51515";
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:str];
NSLog(#"Number here:%#",myNumber);
[f release];
& result print is
2015-03-01 08:09:28.353 myApp [57376:2086924] Number here: 515.5151499999999
Actual debug log picture here
but actually it should be 515.51515 rather 515.5151499999999.
I tried all comibination with f.usesSignificantDigits & f.maximumFractionDigits =10 but no luck.
please let me know How to fix this?
RMaddy is correct, floating point numbers will be a bit off.
Since an NSDecimalNumber is an NSNumber you can use:
NSNumber *number = [NSDecimalNumber decimalNumberWithString:#"515.51515"];
Try to use construction:
NSNumber *myNumber = [NSNumber numberWithFloat:[str floatValue]];
I think it should work correctly.

Formatting a number in ios

I am trying to find a solution to add zeros in the beginning of the number as per the total input provided.
Example:
Number = 100
Total Number of digits = 3
The kind of format i will like to have is 001,002,003 and so on.
Thanks
I found out the solution for the same. Posting it below:
while (totalNumCopy) {
totalNumCopy = totalNumCopy/10;
noOfDigits++;
}
NSMutableString *thumbName = nil;
if(noOfDigits > 0)
{
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setFormatWidth:noOfDigits];
[formatter setPaddingCharacter:#"0"];
[formatter setNumberStyle: NSNumberFormatterPadBeforePrefix];
NSString *stringNumber = [formatter stringFromNumber:[NSNumber numberWithInt:i+1]];
thumbName = [NSString stringWithFormat:#"PageThumb%#.png",stringNumber];
[formatter release];
}
the basic string formatter is like this:
NSLog(#"%03d, %03d, %03d", 1, 2, 3);
the result would be:
001, 002, 003
maybe it helps on you.
NSString *myNumber = [NSString stringWithFormat:#"%03d", number];
i think the above code will help you

How to insert grouping comma in NSString as typed?

A user enters a numerical string in a UILabel and the text is displayed as the user types.
NSString *input = [[sender titleLabel] text];
[display_ setText:[[display_ text] stringByAppendingString:input]];
This works fine and I format the display using NSNumberFormatter so that if 1000000 is entered it is converted to 1,000,000 upon tapping another button.
However, I'd like to get those grouping commas to be displayed as the user types. I can understand how to insert things into strings, but how to do it as the user types is not clear to me. Would this require a mutable string?
Maybe somehow monitor the string length and split it into groups of three and make and display a new string with the commas inserted? I could probably do that, but it is the "as it is typed" part that has me stymied.
Another thought is to append and display the string, then read the display into a new NSString and format it and display it again right away. So I tried that, and it almost works:
if (userIsEntering)
{
NSNumberFormatter *fmtr = [[NSNumberFormatter alloc] init];
[fmtr setNumberStyle:NSNumberFormatterDecimalStyle];
[fmtr setGroupingSeparator:#","];
[fmtr setDecimalSeparator:#"."];
NSString *out = [[display_ text] stringByAppendingString:digit];
NSNumber *num = [fmtr numberFromString:out];
NSString* formattedResult = [fmtr stringFromNumber:num];
[display_ setText: [NSString stringWithFormat:#"%#", formattedResult]];
[fmtr release];
}
And, along with the fact that the formatter is created and released with every digit entered, after 4 digits it returns null.
UPDATE: I figured out how to do it in a label (with some help from #Michael-Frederick). It uses an NSNotification.
This works perfectly for non-decimal numbers, but when I try to enter a decimal point it is ignored and removed. If I do not invoke this method, the decimal point is accepted and all works well.
Numeric entry is as follows (from a button):
NSString *digit = [[sender titleLabel] text];
if (userIsStillWorking_)
{
[display_ setText:[[display_ text] stringByAppendingString:digit]];
}
else
{
[display_ setText: digit];
userIsStillWorking_ = YES;
}
[[NSNotificationCenter defaultCenter] postNotificationName:#"updateDisplay" object:nil];
And the updateDisplay method called by the notification is:
{
NSString *unformattedValue = [display_.text stringByReplacingOccurrencesOfString:
#"," withString:#""];
unformattedValue = [unformattedValue stringByReplacingOccurrencesOfString:
#"." withString:#""];
NSDecimalNumber *amount = [NSDecimalNumber decimalNumberWithString:unformattedValue];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setGroupingSeparator:#","];
[formatter setDecimalSeparator:#"."];
[display_ setText: [ formatter stringFromNumber:amount]];
[formatter release];
}
I've tried commenting out
unformattedValue = [unformattedValue stringByReplacingOccurrencesOfString:
#"." withString:#""];
but that makes no difference.
EDIT:
A user cannot type into a uilabel. You need to use either a uitextfield or a uitextview.
If you want to use a uitextfield, do something like this...
- (void) viewDidLoad {
[super viewDidLoad];
[textField addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
}
- (void) textFieldDidChange:(UITextField *)textField {
NSString *unformattedValue = [textField.text stringByReplacingOccurrencesOfString:#"," withString:#""];
unformattedValue = [unformattedValue stringByReplacingOccurrencesOfString:#"." withString:#""];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setGroupingSeparator:#","];
[formatter setDecimalSeparator:#"."];
NSNumber *amount = [NSNumber numberWithInteger:[unformattedValue intValue]];
textField.text = [formatter stringFromNumber:amount];
[formatter release];
}
Note that you are correct that NSNumberFormatter should be declared outside of the textFieldDidChange method. Note that this code would actually be for an integer. You could have to switch intValue to floatValue if need be. This code is untested, it is more of a general guide.
The best way to do this is to use 2 UIlabels. 1 of the labels is used to feed your NSNumberFormatter object by using [NSString stringByAppendingString:digit]; The other label is actually displayed. The trick is to set the label that is unformatted to hidden and the other label is set as an output for the number formatter. By feeding the hidden label to the number formatter, and outputting the displayed label from the number formatter, the number formatter should be set to the NSDecimalNumber style. Setting it all up this way, the result displayed is automatic commas while typing.

Resources