我在从两个整数进行简单除法时遇到问题。我需要它尽可能准确,但由于某种原因,双重类型的工作很奇怪。
例如,如果我执行以下代码:
double res = (29970.0/1000.0);
结果是 29.969999999999999,而它应该是 29.970。
知道为什么会这样吗?
谢谢
我在从两个整数进行简单除法时遇到问题。我需要它尽可能准确,但由于某种原因,双重类型的工作很奇怪。
例如,如果我执行以下代码:
double res = (29970.0/1000.0);
结果是 29.969999999999999,而它应该是 29.970。
知道为什么会这样吗?
谢谢
知道为什么会这样吗?
因为双重表示是有限的。例如,IEEE754 双精度标准有 52 位表示小数。因此,并未涵盖所有实数。因此,某些值不能理想地精确。在您的情况下,结果与理想值相差 10^-15。
我需要它尽可能准确
那么你不应该使用double
s。例如,在 Java 中,您可以使用BigDecimal
(大多数语言都提供类似的工具)。double
在某种程度上,操作本质上是不准确的。这是由于浮点数的内部表示。
float 和 double 类型的浮点数以二进制格式存储。因此数字不能有精确的十进制值。这些值被量化了。如果您假设只有 2 位小数类型,您将只能表示 2^-2 个量子:0.00 0.25 0.50 0.75,两者之间没有。
我需要它尽可能准确
没有灵丹妙药,但如果您只想要基本的算术运算(将 ℚ 映射到 ℚ),并且您真的想要精确的结果,那么您最好的选择是由两个无限整数(又名 BigInteger、BigInt 等)组成的有理类型。 ——但即便如此,记忆也不是无限的,你必须想一想。
对于问题的其余部分,请阅读有关固定大小浮点数的信息,有很多好的资源。