以下两行的输出似乎表明NSString的stringWithFormat语句不会一致地对数字进行舍入。它似乎从0.75正确地向上舍入到0.8。但它将0.25下降到0.2。这是代码。
NSString *sRoundedScore = [NSString stringWithFormat:@"%.1f", fScore];
NSLog(@"\r\n score before rounding: %f, rounded score: %@", fScore, sRoundedScore);
当fScore被指定为0.25时,输出为:
score before rounding: 0.250000, rounded score: 0.2
当fScore被指定为0.75时,输出为:
score before rounding: 0.750000, rounded score: 0.8
我必须开始使用NSNumberFormatter才能使其始终如一。为什么stringWithFormat会在结果中产生这种变化?
答案 0 :(得分:3)
这个答案可以追溯到“printf”功能
银行家四舍五入:
重要的是要知道这更能说明你想在浮点整数上显示一个小数位。
由于您正在说明一个小数点,因此它会检查第二个小数以确定舍入的位置。 %.f format'er的舍入逻辑就是这样的:如果你的前面的数字小于4,那么如果你的前面的数字是4并且超过5轮,则向下5轮。
原因: http://linuxgazette.net/144/misc/lg/a_question_of_rounding_in_issue_143.html: “对于GNU C库,printf()使用的舍入规则是”银行家四舍五入“或”舍入到偶数“。这比其他一些C库更正确,因为C99规范说转换为十进制应该使用当前选择IEEE舍入模式(默认银行家舍入)。“
从这个答案中找到: printf rounding behavior for doubles
如果你想在上面进行内联的 常见的舍入 ,请使用c函数 round()进行一些数学运算或者你可以按照你的说法简单地使用 NSNumberFormatter 。
答案 1 :(得分:1)
根本问题是当你看到0.25时,这个数字实际上更像是0.2499999999999。有一些标准技术可以实现您想要的舍入。在这种特殊情况下,你可以将float乘以100.0f,然后使用lroundf,并打印long:
float foo = 0.25f;
NSLog(@"First %f", foo);
NSLog(@"Round %.1f", foo);
foo += 0.0000001;
NSLog(@"Second %f", foo);
NSLog(@"Round %.1f", foo);
//2013-07-18 15:36:09.021 EmailAddressFinder[12618:303] First 0.250000
//2013-07-18 15:36:09.022 EmailAddressFinder[12618:303] First 0.2
//2013-07-18 15:36:09.022 EmailAddressFinder[12618:303] Second 0.250000
//2013-07-18 15:36:09.022 EmailAddressFinder[12618:303] Second 0.3
foo = 0.25f;
foo *=100;
long l = lroundf(foo);
NSLog(@"l=%ld", l);
NSLog(@"0.%0.2ld", l); // .2=="print two places", 0=="add a leading 0 if needed"
//2013-07-18 15:37:24.424 EmailAddressFinder[13474:303] 0.25
你需要调整范围等。每当我使用美国货币时,我总是以这种方式舍入到整数美分,并使用一种小方法通过使用相同的技术从美分给我一个dollar.cents字符串
编辑:我看到你给出了答案 - 任何使用printf行为来确定用户将会看到什么的人都会在某些时候遇到问题。将数字合并到您确定的某些内容中,您将拥有强大且可移植的代码。