Ios NSNumber与其浮点值不同

Ios NSNumber与其浮点值不同,ios,objective-c,nsdictionary,nsnumber,Ios,Objective C,Nsdictionary,Nsnumber,我发现了NSNumber的奇怪行为 基本上,我的代码从API调用获取json: id json_response = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error]; 并存储为

我发现了
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):

但是当我检查float值时

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
但是,如果我测试代码并手动将1.05放入
NSDictionary
中,一切都会正常工作


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

问题是1.05的值不能用浮点数精确表示。这仅适用于2的(正或负)幂和的值。因此,可以精确地表示1(=2^0)或1.03125(=2^0+2^-5)之类的值,但1.5的最佳近似值是1.049999523162842。
现在,当您初始化一个
NSNumberFormatter
,并且不设置它的
roundingMode
属性时,它的默认值是
KCFNumberFormatTerroundHalf偶数
,这意味着数字将“向最接近的整数舍入”,或者向等距的偶数舍入。“

因此,如果您的数字是1.0499959523162842,它将四舍五入为1.0,输出为1。

问题是1.05的值不能用浮点数精确表示。这仅适用于2的(正或负)幂和的值。因此,可以精确表示1(=2^0)或1.03125这样的值(=2^0+2^-5),但1.5的最佳近似值为1.0499959523162842。
现在,当您初始化一个
NSNumberFormatter
,并且不设置它的
roundingMode
属性时,它的默认值是
KCFNumberFormatTerroundHalf偶数
,这意味着数字将“向最接近的整数舍入”,或者向等距的偶数舍入。“

因此,如果您的数字是1.049999523162842,它将四舍五入为1.0,输出为1。

不清楚您的问题是什么。
NSNumberFormatter
是否产生了
1
而不是
1.1
?在这种情况下,这是因为它向下舍入了。或者您对数字是
1.04999
而不是
1感到困惑.05
?在这种情况下,这只是一个浮点舍入错误。是的,我感到困惑,因为我有1.05,它应该舍入到1.1而不是1。不清楚你的问题是什么。是
NSNumberFormatter
产生
1
,而不是
1.1
?在这种情况下,这是因为它舍入了。还是你被n弄糊涂了数字是
1.04999
而不是
1.05
?在这种情况下,这只是一个浮点舍入错误。是的,我很困惑,因为我有1.05,它应该舍入到1.1而不是1。这对我来说非常清楚,谢谢。那么如何向最终用户显示正确的数字呢?因为即使使用正确的舍入模式也没有帮助,因为它如果您不想舍入整数,而是要舍入整数的一半(在您的情况下是舍入1,05),则ll舍入1.04999523162842而不是1.05,您可以这样做:如果x是要舍入的值,将2x取整为整数,然后将结果除以2。例如,10499*2=20998,舍入=2,1/2=1,05。但是,如上所述,1,05不能用浮点数精确表示。这对我来说非常清楚,谢谢。那么如何向最终用户显示正确的数字?因为即使使用正确的舍入ing模式将不起作用,因为如果您不想向整数取整,而是向整数的一半取整(在您的情况下是向1,05取整),它将取整1.04999523162842而不是1.05,您可以这样做:如果x是要舍入的值,则将2x舍入为整数,然后将结果除以2。例如,10499*2=20998,舍入=2,1/2=1,05。但是,如上所述,1,05不能用浮点数精确表示。
    avg = roundf(avg * 100); // here 105
    avg = avg / 100; // and here is  1.0499999523162842 again