C++除以 0.0 与 DBL_MIN

发布于 2024-09-03 00:40:20 字数 734 浏览 10 评论 0原文

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

除以 0.0 和 MIN_DBL 在游戏中产生相同的结果,因为 1/0.0< /code> 和 1/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

When finding the inverse square root of a double, is it better to clamp invalid non-positive inputs at 0.0 or MIN_DBL? (In my example below double b may end up being negative due to floating point rounding errors and because the laws of physics are slightly slightly fudged in the game.)

Both division by 0.0 and MIN_DBL produce the same outcome in the game because 1/0.0 and 1/DBL_MIN are effectively infinity. My intuition says MIN_DBL is the better choice, but would there be any case for using 0.0? Like perhaps sqrt(0.0), 1/0.0 and multiplication by 1.#INF000000000000 execute faster because they are special cases.

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);

double division in MSVC:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

善良天后 2024-09-10 00:40:20

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

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

When dealing with floating point math, "infinity" and "effectively infinity" are quite different. Once a number stops being finite, it tends to stay that way. So while the value of lorentz_factor is "effectively" the same for both methods, depending on how you use that value, later computations can be radically different. sqrt(lorentz_factor) for instance remains infinite if you clamp to 0, but will actually be calculated if you clamp to some very very small number.

So the answer will largely depend on what you plan on doing with that value once you've clamped it.

白云悠悠 2024-09-10 00:40:20

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

Why not just assign INF to lorentz_factor directly, avoiding both the sqrt call and the division?

double lorentz_factor;
if (b <= 0.0) 
    lorentz_factor = std::numeric_limits<double>::infinity();
else
    lorentz_factor = 1/sqrt(b);
  • You'll need to #include <limits> for this.
  • You can also use ::max() instead of ::infinity(), if that's what you need.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文