【问题标题】:C++ double division by 0.0 versus DBL_MINC++ 双除以 0.0 与 DBL_MIN
【发布时间】:2011-02-23 13:20:14
【问题描述】:

当求双精度的平方根的反比时,最好将无效的非正输入钳制在 0.0 或 MIN_DBL 处? (在我下面的示例中,double b 最终可能是由于浮点舍入误差和物理定律在游戏中略有捏造,因此为负数。)

除以 0.0 和 MIN_DBL 在游戏中产生相同的结果,因为 1/0.01/DBL_MIN 实际上是无穷大。 我的直觉说 MIN_DBL 是更好的选择,但是否有任何情况下使用 0.0? 可能像 sqrt(0.0)1/0.0 和乘以 1.#INF000000000000 执行得更快,因为它们是特殊情况。

double b = 1 - v.length_squared()/(c*c);

#ifdef CLAMP_BY_0
if (b < 0.0) b = 0.0;
#endif

#ifdef CLAMP_BY_DBL_MIN
if (b <= 0.0) b = DBL_MIN;
#endif

double lorentz_factor = 1/sqrt(b);

MSVC 中的双除法:

1/0.0 = 1.#INF000000000000 1/DBL_MIN = 4.4942328371557898e+307

【问题讨论】:

    标签: c++ double msvcrt infinity divide-by-zero


    【解决方案1】:

    在处理浮点数学时,“无穷大”和“有效无穷大”是完全不同的。一旦一个数字不再是有限的,它就会保持这种状态。因此,虽然lorentz_factor 的值对于两种方法“实际上”相同,但取决于您如何使用该值,以后的计算可能会完全不同。 sqrt(lorentz_factor) 例如,如果你钳制到 0,它仍然是无限的,但如果你钳制到某个非常小的数字,它实际上会被计算出来。

    因此,答案很大程度上取决于您在确定该值后打算如何处理该值。

    【讨论】:

      【解决方案2】:

      为什么不直接将INF 分配给lorentz_factor,避免sqrt 调用和除法?

      double lorentz_factor;
      if (b <= 0.0) 
          lorentz_factor = std::numeric_limits<double>::infinity();
      else
          lorentz_factor = 1/sqrt(b);
      
      • 为此,您需要#include &lt;limits&gt;
      • 如果您需要,您也可以使用::max() 代替::infinity()

      【讨论】:

        猜你喜欢
        • 2011-11-14
        • 2013-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多