【问题标题】:Losing accuracy with double division双除法会丢失精度
【发布时间】:2013-07-23 17:21:13
【问题描述】:

我遇到了两个整数的简单除法问题。我需要它尽可能准确,但由于某种原因,双重类型的工作很奇怪。

例如,如果我执行以下代码:

double res = (29970.0/1000.0); 

结果是 29.969999999999999,而应该是 29.970。

知道为什么会这样吗?

谢谢

【问题讨论】:

    标签: double


    【解决方案1】:

    知道为什么会这样吗?

    因为双重表示是有限的。例如,IEEE754 double-precision 标准有 52 位表示分数。因此,并未涵盖所有实数。因此,某些值不能理想地精确。在您的情况下,结果与理想值相差 10^-15。

    【讨论】:

    • So, the values will be always not ideally precise. 不正确。有时这些值会非常精确。
    • @EvgeniSergeev 是的,我解决了这个问题。
    【解决方案2】:

    我需要它尽可能准确

    那么你不应该使用doubles。例如,在 Java 中,您可以改用 BigDecimal(大多数语言都提供类似的功能)。 double 操作在某种程度上本质上是不准确的。这是由于floating point numbersinternal representation

    【讨论】:

    • 当然,除非您尝试计算像 1./3. 这样的东西,这在两种表示中都是不精确的。
    • 十进制变量更适用于具有短十进制表示的数字(例如,金额),但当然它们也具有本质上有限的精度,就像浮点数一样。对于像 pi 这样的值,浮点与十进制变量的精度主要取决于编译器用于该特定变量类型的字节数。
    【解决方案3】:

    float 和 double 类型的浮点数以二进制格式存储。因此数字不能有精确的十进制值。这些值被量化了。如果您假设只有 2 位小数类型,您将只能表示 2^-2 个量子:0.00 0.25 0.50 0.75,两者之间没有。

    【讨论】:

      【解决方案4】:

      我需要它尽可能准确

      没有灵丹妙药,但如果您只想要基本的算术运算(将 ℚ 映射到 ℚ),并且您真的想要精确的结果,那么您最好的选择是由两个无限整数(又名 BigInteger、BigInt、等等)——但即便如此,记忆也不是无限的,你必须考虑一下。

      对于问题的其余部分,请阅读有关固定大小浮点数的信息,有很多好的资源。

      【讨论】:

        猜你喜欢
        • 2012-05-13
        • 2013-06-17
        • 1970-01-01
        • 2010-10-16
        • 2011-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多