C++除以 0.0 与 DBL_MIN
求双精度数的反平方根时,将无效的非正输入钳位在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在处理浮点数学时,“无穷大”和“有效无穷大”有很大不同。一旦一个数字不再是有限的,它就会保持这种状态。因此,虽然两种方法的 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.
为什么不直接将
INF
分配给lorentz_factor
,从而避免sqrt
调用和除法呢?#include
。::max()
代替::infinity()
。Why not just assign
INF
tolorentz_factor
directly, avoiding both thesqrt
call and the division?#include <limits>
for this.::max()
instead of::infinity()
, if that's what you need.