When I convert NSNumber to float value using 'floatValue', there is a difference in precision. Example, I have a NSNumber 'myNumber' having value 2.3, and if I convert myNumber to float using 'floatValue', its value becomes, 2.29999. But I need exactly 2.30000. There is no problem with number of zeros after 2.3, I need '2.3' instead of '2.9'.
How can I do so?
I had similar situation where I was reading value and assigning it back to float variable again.
My Problem statement:
NSString *value = #"553637.90";
NSNumber *num = #([value floatValue]); // 1. This is the problem. num is set to 553637.875000
NSNumberFormatter *decimalStyleFormatter = [[NSNumberFormatter alloc] init];
[decimalStyleFormatter setMaximumFractionDigits:2];
NSString *resultString = [decimalStyleFormatter stringFromNumber:num]; // 2. string is assigned with rounded value like 553637.88
float originalValue = [resultString floatValue]; // 3. Hence, originalValue turns out to be 553637.88 which wrong.
Following worked for me after changing lines:
NSNumber *num = #([value doubleValue]); // 4. doubleValue preserves value 553637.9
double originalvalue = [resultString doubleValue]; // 5. While reading back, assign to variable of type double, in this case 'originalValue'
I hope this would be helpful. :)
If you need exact precision, don't use float. Use a double if you need better precision. That still won't be exact. You could multiply myNumber by 10, convert to an unsigned int and perform your arithmetic on it, convert back to a float or double and divide by 10 and the end result might be more precise. If none of these are sufficiently precise, you might want to look into an arbitrary precision arithmetic library such as GNU MP Bignum.
I've done the following but it is showing me correctly
NSNumber *num = [NSNumber numberWithFloat:2.3];
float f = [num floatValue];
NSLog(#"%f", f);
You can play with something like this:
float x = 2.3f;
NSNumber *n = [NSNumber numberWithFloat:x];
NSNumberFormatter *fmt = [[NSNumberFormatter alloc] init];
[fmt setPositiveFormat:#"0.#"];
NSString *s = [fmt stringFromNumber:n];
float f = [s floatValue];
Related
How can I convert a NSString containing a number of any primitive data type (e.g. int, float, char, unsigned int, etc.)? The problem is, I don't know which number type the string will contain at runtime.
I have an idea how to do it, but I'm not sure if this works with any type, also unsigned and floating point values:
long long scannedNumber;
NSScanner *scanner = [NSScanner scannerWithString:aString];
[scanner scanLongLong:&scannedNumber];
NSNumber *number = [NSNumber numberWithLongLong: scannedNumber];
Thanks for the help.
Use an NSNumberFormatter:
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
f.numberStyle = NSNumberFormatterDecimalStyle;
NSNumber *myNumber = [f numberFromString:#"42"];
If the string is not a valid number, then myNumber will be nil. If it is a valid number, then you now have all of the NSNumber goodness to figure out what kind of number it actually is.
You can use -[NSString integerValue], -[NSString floatValue], etc. However, the correct (locale-sensitive, etc.) way to do this is to use -[NSNumberFormatter numberFromString:] which will give you an NSNumber converted from the appropriate locale and given the settings of the NSNumberFormatter (including whether it will allow floating point values).
Objective-C
(Note: this method doesn't play nice with difference locales, but is slightly faster than a NSNumberFormatter)
NSNumber *num1 = #([#"42" intValue]);
NSNumber *num2 = #([#"42.42" floatValue]);
Swift
Simple but dirty way
// Swift 1.2
if let intValue = "42".toInt() {
let number1 = NSNumber(integer:intValue)
}
// Swift 2.0
let number2 = Int("42')
// Swift 3.0
NSDecimalNumber(string: "42.42")
// Using NSNumber
let number3 = NSNumber(float:("42.42" as NSString).floatValue)
The extension-way
This is better, really, because it'll play nicely with locales and decimals.
extension String {
var numberValue:NSNumber? {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
return formatter.number(from: self)
}
}
Now you can simply do:
let someFloat = "42.42".numberValue
let someInt = "42".numberValue
For strings starting with integers, e.g., #"123", #"456 ft", #"7.89", etc., use -[NSString integerValue].
So, #([#"12.8 lbs" integerValue]) is like doing [NSNumber numberWithInteger:12].
You can also do this:
NSNumber *number = #([dictionary[#"id"] intValue]]);
Have fun!
If you know that you receive integers, you could use:
NSString* val = #"12";
[NSNumber numberWithInt:[val intValue]];
Here's a working sample of NSNumberFormatter reading localized number NSString (xCode 3.2.4, osX 10.6), to save others the hours I've just spent messing around. Beware: while it can handle trailing blanks ("8,765.4 " works), this cannot handle leading white space and this cannot handle stray text characters. (Bad input strings: " 8" and "8q" and "8 q".)
NSString *tempStr = #"8,765.4";
// localization allows other thousands separators, also.
NSNumberFormatter * myNumFormatter = [[NSNumberFormatter alloc] init];
[myNumFormatter setLocale:[NSLocale currentLocale]]; // happen by default?
[myNumFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
// next line is very important!
[myNumFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; // crucial
NSNumber *tempNum = [myNumFormatter numberFromString:tempStr];
NSLog(#"string '%#' gives NSNumber '%#' with intValue '%i'",
tempStr, tempNum, [tempNum intValue]);
[myNumFormatter release]; // good citizen
I wanted to convert a string to a double. This above answer didn't quite work for me. But this did: How to do string conversions in Objective-C?
All I pretty much did was:
double myDouble = [myString doubleValue];
Thanks All! I am combined feedback and finally manage to convert from text input ( string ) to Integer. Plus it could tell me whether the input is integer :)
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:thresholdInput.text];
int minThreshold = [myNumber intValue];
NSLog(#"Setting for minThreshold %i", minThreshold);
if ((int)minThreshold < 1 )
{
NSLog(#"Not a number");
}
else
{
NSLog(#"Setting for integer minThreshold %i", minThreshold);
}
[f release];
I think NSDecimalNumber will do it:
Example:
NSNumber *theNumber = [NSDecimalNumber decimalNumberWithString:[stringVariable text]]];
NSDecimalNumber is a subclass of NSNumber, so implicit casting allowed.
What about C's standard atoi?
int num = atoi([scannedNumber cStringUsingEncoding:NSUTF8StringEncoding]);
Do you think there are any caveats?
You can just use [string intValue] or [string floatValue] or [string doubleValue] etc
You can also use NSNumberFormatter class:
you can also do like this code 8.3.3 ios 10.3 support
[NSNumber numberWithInt:[#"put your string here" intValue]]
NSDecimalNumber *myNumber = [NSDecimalNumber decimalNumberWithString:#"123.45"];
NSLog(#"My Number : %#",myNumber);
Try this
NSNumber *yourNumber = [NSNumber numberWithLongLong:[yourString longLongValue]];
Note - I have used longLongValue as per my requirement. You can also use integerValue, longValue, or any other format depending upon your requirement.
Worked in Swift 3
NSDecimalNumber(string: "Your string")
I know this is very late but below code is working for me.
Try this code
NSNumber *number = #([dictionary[#"keyValue"] intValue]]);
This may help you. Thanks
extension String {
var numberValue:NSNumber? {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
return formatter.number(from: self)
}
}
let someFloat = "12.34".numberValue
I am trying to convert the value to float with 2 precision decimal format.
NSString* formattedNumber = [NSString stringWithFormat:#"%.2lu", (unsigned long)users.count];
float totalRatingCount = atof([formattedNumber UTF8String]);
This gives me values such as
1.000000
2.000000
3.000000
What I want is the following
1.00
2.00
3.00
Where am i going wrong?
A float has no precision value, it's not a fixed point value. However, there is an easier way to convert to float:
CGFloat totalRating = [formattedNumber floatValue];
to print a float with 2dp's of precision, use the format string #"%.02f"
You need to use %.2f format specifier as
NSString* formattedNumber = [NSString stringWithFormat:#"%.2f", (float)users.count];
float totalRatingCount = atof([formattedNumber UTF8String]);
and you'll get the desired out put with 2 values precision after decimal.
Using NSNumberFormatter, you can rounding number up to two digit.
double d = 12.1278;
NSNumberFormatter *formatter = [NSNumberFormatter new];
[formatter setRoundingMode:NSNumberFormatterRoundFloor];
[formatter setMinimumFractionDigits:2];
[formatter setMaximumFractionDigits:2];
NSString *numberString = [formatter stringFromNumber:#(d)];
NSLog(#"numberString: %#", numberString);
Output is :
numberString: 12.12
Try this:
NSNumber *number = [NSNumber numberWithFloat:(unsigned long)users.count];
NSNumberFormatter* nf=[[NSNumberFormatter alloc]init];
nf.minimumFractionDigits=2;
nf.maximumFractionDigits=2;
NSString* str = [nf stringFromNumber:number];
NSLog(#"%#",str);
Given the NSString "1.625", I want to round this to "1.63".
How in the world do I do that?
This is what i have now:
NSString *rateString = [NSString stringWithFormat:#"%.2f", [#"1.63" doubleValue]];
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
item.rate = [f numberFromString:rateString];;
However, doubleValue converts 1.625 to 1.6249999999
So when I round it to two decimal digits with #"%.2f", I end up with 1.62!
If you wanna round to the nearest hundredths, multiply by 100, increment by .5 and divide by 100. Then get the floor of that value.
double rate = [#"1.625" doubleValue];
double roundedNumber = floor(rate * 100 + 0.5) / 100;
NSString *rateString = [NSString stringWithFormat:#"%.2f", roundedNumber];
NSLog(#"rate: %#", rateString);
Running this then outputting the result:
2015-01-13 15:41:08.702 Sandbox[22027:883332] rate: 1.63
If you need high precision what you really need is NSDecimalNumberclass maybe coupled with NSDecimalNumberHandler if don't need to configure all details, or NSDecimalNumberBehaviors if need absolute control. This is the quickest solution to keep 2 decimal digits (the 'scale' value in handler init):
NSDecimalNumberHandler *handler = [[NSDecimalNumberHandler alloc]initWithRoundingMode:NSRoundBankers
scale:2
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:NO];
[NSDecimalNumber setDefaultBehavior:handler];
NSString *string = #"1.63";
NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:string];
NSDecimalNumber docs:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDecimalNumber_Class/index.html
NSDecimalNumberHandler docs:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDecimalNumberHandler_Class/index.html
NSDecimalNumberBehaviors docs:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSDecimalNumberBehaviors_Protocol/index.html
Yes. You are right. Of Course this is a duplicate question. Before flag my question, please continue reading below.
I want to round a float value, which is
56.6748939 to 56.7
56.45678 to 56.5
56.234589 to 56.2
Actually it can be any number of decimal precisions. But I want to round it to nearest value. (If it is greater than or equal to 5, then round up and if not, then round down).
I can do that with the below code.
float value = 56.68899
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc]init];
[numberFormatter setMaximumFractionDigits:1];
[numberFormatter setRoundingMode:NSNumberFormatterRoundUp];
NSString *roundedString = [numberFormatter stringFromNumber:[NSNumber numberWithFloat:value]];
NSNumber *roundedNumber = [NSNumber numberFromString:roundedString];
float roundedValue = [roundedNumber floatValue];
Above code looks like a long process. I have several numbers to round off. So this process is hard to convert a float value into NSNumber and to NSString and to NSNumber and to float.
Is there any other easy way to achieve what I asked ?
I still have a doubt in the above code. It says roundUp. So when it comes to roundDown, will it work?
Can't you simply multiply by 10, round the number, then divide by 10?
Try
CGFloat float1 = 56.6748939f;
CGFloat float2 = 56.45678f;
NSLog(#"%.1f %.1f",float1,float2);
56.7 56.5
EDIT :
float value = 56.6748939f;
NSString *floatString = [NSString stringWithFormat:#"%.1f",floatValue];
float roundedValue = [floatString floatValue];
NSString* strr=[NSString stringWithFormat: #"%.1f", 3.666666];
NSLog(#"output is: %#",strr);
output is:3.7
float fCost = [strr floatValue];
This works for me
NSNumberFormatter* formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:1];
[formatter setMinimumFractionDigits:0];
CGFloat firstnumber = 56.6748939;
NSString *result1 = [formatter stringFromNumber:[NSNumber numberWithFloat:firstnumber]];
NSLog(#"RESULT #1: %#",result1);
CGFloat secondnumber = 56.45678;
NSString *result2 = [formatter stringFromNumber:[NSNumber numberWithFloat:secondnumber]];
NSLog(#"RESULT #2: %#",result2);
CGFloat thirdnumber = 56.234589;
NSString *result3 = [formatter stringFromNumber:[NSNumber numberWithFloat:thirdnumber]];
NSLog(#"RESULT #2: %#",result3);
You don't want float, because that only gives you six or seven digits precision. You also don't want CGFloat, because that only gives you six or seven digits precision except on an iPad Air or iPhone 5s. You want to use double.
Rounding to one digit is done very simply:
double x = 56.6748939;
double rounded = round (10 * x) / 10;
You can use
[dictionaryTemp setObject:[NSString stringWithFormat:#"%.1f",averageRatingOfAllOrders] forKey:#"AvgRating"];
%.1f will give us value 2.1 only one digit after decimal point.
Try this :
This will round to any value not limited by powers of 10.
extension Double {
func roundToNearestValue(value: Double) -> Double {
let remainder = self % value
let shouldRoundUp = remainder >= value/2 ? true : false
let multiple = floor(self / value)
let returnValue = !shouldRoundUp ? value * multiple : value * multiple + value
return returnValue
}
}
Say I have the following values for these ivars:
NSString* percentage = 35
NSString* value = 146
In my code below I am expecting to get 51.1 when I do my multiplication (146*.35) but instead am getting 100.
- (NSDecimalNumber*) getProductByPercentage : (NSArray*) itemsToMultiply : (float) annualPatients {
//get items from array
NSString* percentage = [itemsToMultiply objectAtIndex:0];
NSString* value = [itemsToMultiply objectAtIndex:1];
//init a number formatter
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
//set its formatting style
[f setNumberStyle:NSNumberFormatterDecimalStyle];
//convert to percentage
float thisPercentage = [percentage floatValue]/100;
//convert to NSDecimal
NSDecimalNumber* decPercentage = [[NSDecimalNumber alloc] initWithString:[NSString stringWithFormat:#"%f", thisPercentage]];
NSDecimalNumber* decAvgReimbursement = [[NSDecimalNumber alloc] initWithString: value];
NSDecimalNumber* decAnnualPatients = [[NSDecimalNumber alloc] initWithString:[NSString stringWithFormat:#"%f", annualPatients]];
//set up handler
NSDecimalNumberHandler *handler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
scale:-2
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:NO
];
//get our results
NSDecimalNumber* decAvgCost = [decAvgReimbursement decimalNumberByMultiplyingBy:decPercentage
withBehavior:handler];
NSLog(#"%#::%#::%#", decAvgCost, decAvgReimbursement, decPercentage);
return decAvgCost;
}
Here's my log output
2013-02-04 13:57:46.960 EUS Calculator[34154:c07] 100::146::0.35
Is there something wrong with my handler that is getting me the wrong results?
scale:-2
You're setting the scale to round to -2 decimals, that is to the closest 100.
You're rounding to the wrong scale. Try changing the scale to 0 (removes decimal point) and try again. If you want 1 decimal place, use a scale of 1; you should get 51.1 then.
Change this:
float thisPercentage = [percentage floatValue]/100;
to this:
float thisPercentage = [percentage floatValue]/100.0;
If you don't put the .0, then the compiler interprets it as an integer number, and when doing float/int it will convert it to int, transforming your expected 0.35 to 0.
Also, you aren't using your NSNumberFormatter anywhere, so you might as well not even create it.
Why are you using NSDecimalNumbers anyways?