C ++双除以0.0与DBL_MIN

时间:2010-05-25 06:37:49

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

当找到double的反平方根时,将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

2 个答案:

答案 0 :(得分:2)

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

所以答案在很大程度上取决于你在计算它之后计划用这个值做什么。

答案 1 :(得分:0)

为什么不直接将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 <limits>
  • 您也可以使用::max()代替::infinity(),如果您需要的话。