我出现了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,一切都按预期工作。
如果有人可以解释为什么会这样?以及如何保持每次正确显示?
答案 0 :(得分:4)
问题是1.05的值不能用浮点数精确表示。这仅适用于2的(正或负)幂之和的值。因此,可以精确地表示诸如1(= 2 ^ 0)或1.03125(= 2 ^ 0 + 2 ^ -5)之类的值,但是在您的情况下,最佳近似值为1.0499999523162842
现在,当您初始化NSNumberFormatter
并且未设置其roundingMode
属性时,其默认值为kCFNumberFormatterRoundHalfEven
,这意味着该数字将舍入“朝向最接近的整数,或朝向均匀数字等于等距。“
因此,如果您的数字是1.0499999523162842,它将四舍五入为1.0,并输出为1.