NSNumber 与其 floatValue 不同

问题描述 投票:0回答:1

我发现了

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

即使我尝试将其四舍五入到小数点后两位

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

但是,如果我测试代码并手动将 1.05 放入

NSDictionary
中,一切都会按预期工作。

如果有人可以解释这是为什么?以及如何保存每次正确的显示?

ios objective-c nsdictionary nsnumber
1个回答
4
投票

问题是1.05的值无法用浮点数精确表示。这仅适用于 2 的(正或负)幂之和的值。因此,可以精确地表示 1 (=2^0) 或 1.03125 (= 2^0 + 2^-5) 等值,但是1.5 的最佳近似值是您的情况 1.0499999523162842。
现在,当您初始化

NSNumberFormatter
并且不设置其
roundingMode
属性时,其默认值为
kCFNumberFormatterRoundHalfEven
,这意味着数字将“向最接近的整数舍入,如果等距则向偶数舍入。”
因此,如果您的数字是 1.0499999523162842,它将四舍五入为 1.0,并且输出为 1。

© www.soinside.com 2019 - 2024. All rights reserved.