我一直在解决UVA中的编程挑战并遇到了这个问题,这真的很奇怪。这是有缺陷的代码:
program WTF;
begin
WriteLn(Trunc(2.01 * 100));
ReadLn();
end.
显然,我需要将201
作为Integer
,但我得到200
,这是因为Double某种方式没有存储确切的值...它是{{1}由于我不知道的原因,有人可以解释这个并提供解决方案吗?
编辑:然而,我发现使用2.01 = 2.00(9)
代替Round()
修复此问题......但是,为什么Trunc()
无法正常工作?
答案 0 :(得分:3)
Double
存储s * 2 p 形式的数字,其中s和p是整数。对于任何整数s,p,数字2.01的形式不是s * 2 p ,因此它不能完全存储在Double
中。
这里的解决方案是将2.01 * 100
舍入到最接近的整数而不是截断它。虽然2.01
不完全是2.01,但它只有一点点。舍入到最接近的整数将导致201。
请注意,如果按2.00(9)
表示2.0099999999…
无限期重复,那么2.00(9)
<{1}},当你写Double
时2.01
1}}。与真实2.01最接近的Double
和您获得的数字是2.0099999999999997868371792719699442386627197265625
。它的形式为s * 2 p :9052235251014696 * 2 -52