【问题标题】:Why does division(?) yield this number?为什么除法(?)会产生这个数字?
【发布时间】:2010-11-24 04:28:42
【问题描述】:

改写问题:

以下代码(不是 C++ - 用内部脚本语言编写)

if(A*B != 0.0)
{
   D = (C/(A*B))*100.0;
}
else
{
   D = 0.0;
}

产生一个值

90989373681853939930449659398190196007605312719045829137102976436641398782862768335320454041881784565022989668056715169480294533394160442876108458546952155914634268552157701346144299391656459840294022732906509880379702822420494744472135997630178480287638496793549447363202959411986592330337536848282003701760.000000

对于 D。我们 100% 确定 A != 0.0。我们几乎 100% 确定 B == 0.0。我们从不使用这种无限小的值(接近 0.0 但不是 0.0),例如 B 的值所暗示的 C 的值。它不可能从我们的数据中获得这种价值。当B 为 0 时,A*B 可以产生不等于 0.0 的任何东西吗?

【问题讨论】:

  • 所以如果这不是 C++,为什么它有一个 C++ 标签? (当然,您希望人们如何向您解释您自己的内部脚本语言是如何工作的?;))

标签: c++ floating-point division divide-by-zero


【解决方案1】:

您除以的数字不是实际上是 0,只是非常非常接近。

【讨论】:

    【解决方案2】:

    假设您使用的是 IEEE 浮点数,在这种情况下对浮点数使用相等或不相等并不是一个好主意。即使像 -0.0 和 +0.0 这样的相同值,从按位角度来看它们也不相等,这就是等价的作用。即使使用其他浮点格式,也不鼓励使用 equal 和 not equal。

    取而代之的是在其上添加某种范围 e=a*b;如果 ((e0.0002) 那么...

    【讨论】:

      【解决方案3】:

      这看起来像你之前的计算产生了错误,所以你的除法是一个非常小的小数,但不是零。如果你想捕捉这样的东西,你应该添加一个误差范围,伪代码:if(num < margin_of_error) ret inf;,或者使用 epsilon 方法更安全

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-09-23
        • 1970-01-01
        • 2016-11-19
        • 2012-08-08
        • 2017-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多