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