put*_*idp 3 c floating-point objective-c
我试图将浮动显示只有一个小数点.我得到了意想不到的结果如下:
码:
float a = 1.25;
float b = 1.35;
NSLog(@"1.25 -> %.1f\n1.35 -> %.1f",a,b);
Run Code Online (Sandbox Code Playgroud)
输出:
1.25 - > 1.2
1.35 - > 1.4
预期产出,或者:
1.25 - > 1.3
1.35 - > 1.4
要么:
1.25 - > 1.2
1.35 - > 1.3
这仅仅是由于二进制和十进制之间的内部转换?如果是这样,我如何获得预期的行为?
我正在使用Xcode 4.6.
编辑:好的,感谢TonyK和H2CO3,这是由于小数的二进制表示.
float a = 1.25;
float b = 1.35;
NSLog(@"1.25 -> %.30f\n1.35 -> %.30f",a,b);
Run Code Online (Sandbox Code Playgroud)
1.25 - > 1.250000000000000000000000000000
1.35 - > 1.350000000000000088817841970013
很多好消息,但据我所知,没有人接近第二个问题:我如何得到预期的行为?
Objective-C中的舍入数字是一个完全不同的问题.
1.35是27/20,二进制是
1.01 0110 0110 0110 0110 0110 0110....
Run Code Online (Sandbox Code Playgroud)
A float在大多数系统上都有一个23位的尾数(不计算隐含的前导1.),所以这会被四舍五入到
1.01 0110 0110 0110 0110 0110 1
Run Code Online (Sandbox Code Playgroud)
(因为0110明确地大于1000的一半).所以当它printf看到时它严格大于1.35 .因此1.4.
对于1.25,这在二进制中完全可以表示为
1.01
Run Code Online (Sandbox Code Playgroud)
所以printf看到它的确切价值.但是如何围绕1.25呢?我们在学校教授第5轮到第10轮.但是大多数现代系统在硬件级别使用称为"round to even"的默认舍入模式,因为它减少了累积舍入误差的影响.这意味着当一个数字正好在两个最接近的舍入候选者之间时,它会四舍五入到偶数候选者.
所以似乎print是使用"round to even"进行十进制输出!我在这个ideone链接检查了这个假设,确实1.75被四舍五入到1.8.这对我来说是一个惊喜,但不是一个巨大的.