I'm trying to save a float to an nsnumber but i just want to save it with two decimal places. I know I can do it by converting to an NSString
first using this code
NSString* formattedNumber = [NSString stringWithFormat:@"%.02f", myFloat];
but seems clumsy. All I want to do is convert
float numb = 23.25454 into NSNumber 23.25
Just round it using any of these functions
float rounded = round(val * 100) / 100;
float rounded_down = floorf(val * 100) / 100;
float nearest = floorf(val * 100 + 0.5) / 100;
float rounded_up = ceilf(val * 100) / 100;
If you're looking for an object oriented approach, try using NSDecimalNumber
which is a subclass of NSNumber
. Init the NSDecimalNumber with your float value and then call decimalNumberByRoundingAccordingToBehavior:
. This gives you a few options of how the truncation or rounding occurs with NSDecimalNumberBehaviors
, where you can set the scale (number of digits following the decimal) and an NSRoundingMode. Check the docs for more info.
Use this
float numb = 23.25454;
NSNumber *num = @((int)(numb*100)/100.0);
It is impossible to do this with float
, double
, or either of those wrapped as an NSNumber
. You need to understand how floating point works.
All these use binary numbers, you wish to represent a number with exactly two decimal places. A binary fraction is made up from a sum of 1/2, 1/4, 1/8, 1/16... while a decimal fraction is a sum of 1/10, 1/100, 1/1000... Not all values which can be represented as a sum of values in one of this series can be represented as a sum in the other. This is a similar issue to representing 1/3 in decimal, it is 3/10 + 3/100 + 3/1000 + .....
Try writing, for example, 0.17 = 17/100 = 1/10 + 7/100 as a sum of 1/2, 1/4 etc. Well it's 1/8 + 9/200 = 1/8 + 1/32 + 11/8000 (I'm just doing this on the fly, excuse any errors!) = you figure it out!
To address this there is the NSDecimalNumber
class , which is a subclass of NSNumber
and represents numbers in base-10. The class provides the basic operations to do base-10 arithmetic. You can't mix arithmetic easily between base-10 and base-2 numbers, you cannot even create an NSDecimalNumber
directly from a float
or double
- you format the later as an NSString
(ie convert them to a base-10 representation) - and extracting a double
value with the doubleValue
method is described as:
The approximate value of the receiver as a
double
.
Note the approximate .
So a long answer to get to a question: do you really want to store a float
or double
value to exactly two decimal places?
You can use the round
, floor
& ceil
families to do it approximately, but be prepared for results that are "wrong". Eg try:
float a = 371371.28127;
float b = roundf(a * 100.0) / 100.0;
NSLog(@"a: %f | b: %f", a, b);
HTH
float numb = 23.25454;
float myFloat = roundf(100 * numb) / 100.0;
NSNumber *number = [NSNumber numberWithFloat:myFloat];
NSDecimalNumber with NSDecimalNumberHandler is the best way to get accurate precisions if you want as Object. Below is the sample code.
-(NSDecimalNumber *)getRoundedNumberAfterPointDigitsCount:(int)digitsCount withDouble:(double)doubleValue{
NSDecimalNumber *decimalNumber = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%f",doubleValue]];
NSDecimalNumberHandler *decimalHandler = [[NSDecimalNumberHandler alloc] initWithRoundingMode:NSRoundPlain scale:digitsCount raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];
decimalNumber = [decimalNumber decimalNumberByRoundingAccordingToBehavior:decimalHandler];
return decimalNumber;
}
There is more of Rounding option available with NSRoundingMode.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.