NSNumber与其floatValue

时间:2016-01-25 14:48:21

标签: ios objective-c nsdictionary nsnumber

我出现了NSNumber的奇怪行为。

基本上我的代码从API调用中获取json:

id json_response = [NSJSONSerialization
                             JSONObjectWithData:data
                             options:NSJSONReadingMutableLeaves
                             error:&error];

并存储为NSDictionary

然后我从中获取NSNumber并使用NSNumberFormatter将其转换为字符串,但是......

NSNumber * avgNumber = [[_tableDataArray objectAtIndex:index ]
                            objectForKey:kTrendsKeyAvgScoreFloat];

这里是格式化输出:

 NSNumberFormatter * formatter = [[NSNumberFormatter alloc]init];
[formatter setDecimalSeparator:@","];
[formatter setMaximumFractionDigits:1];
[formatter setMinimumFractionDigits:0];
[formatter setGroupingSeparator:@"."];
[formatter setGroupingSize:3];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSString * retString = [formatter stringFromNumber:number];

NSNumber的值为1.05

时,我的行为很奇怪
(__NSCFNumber *) avgNumber = 0x0000000155923800 (float)1.050000

但是上面的代码是打印(而不是预期的1.1):

1

然而,当我检查浮动值

float avg = [avgNumber floatValue];

事实证明

    Printing description of avg:
(double) avg = 1.0499999523162842

即使我尝试将其舍入到2个小数点

    avg = roundf(avg * 100); // here 105
    avg = avg / 100; // and here is  1.0499999523162842 again

但是,如果我测试代码并在NSDictionary内手动放置1.05,一切都按预期工作。

如果有人可以解释为什么会这样?以及如何保持每次正确显示?

1 个答案:

答案 0 :(得分:4)

问题是1.05的值不能用浮点数精确表示。这仅适用于2的(正或负)幂之和的值。因此,可以精确地表示诸如1(= 2 ^ 0)或1.03125(= 2 ^ 0 + 2 ^ -5)之类的值,但是在您的情况下,最佳近似值为1.0499999523162842 现在,当您初始化NSNumberFormatter并且未设置其roundingMode属性时,其默认值为kCFNumberFormatterRoundHalfEven,这意味着该数字将舍入“朝向最接近的整数,或朝向均匀数字等于等距。“
因此,如果您的数字是1.0499999523162842,它将四舍五入为1.0,并输出为1.