对向量的 GLM 运算返回不正确的值

glm operation over vectors return incorrect values

提问人:DENIS KOVALENKO 提问时间:7/10/2023 更新时间:7/10/2023 访问量:42

问:

Glm 在内部使用 float 并以非常高的精度评估值。问题在于,使用此类值的常规操作可能会返回不正确的结果。考虑以下 gdb 输出:

49                              return glm::normalize(coord - center);
(gdb) p coord
$1 = {{x = -1.30530175e+38, r = -1.30530175e+38, s = -1.30530175e+38}, {y = -2.65845583e+36, g = -2.65845583e+36, 
    t = -2.65845583e+36}, {z = 3.40282347e+38, b = 3.40282347e+38, p = 3.40282347e+38}}
(gdb) p center
$2 = {{x = -2, r = -2, s = -2}, {y = 0, g = 0, t = 0}, {z = 8, b = 8, p = 8}}
(gdb) 

我们有一个向量,其值有很多小数位,而向量的值根本没有任何小数位。超过这些向量的结果如下:coordcenterglm::normalize

Value returned is $14 = {{x = -0, r = -0, s = -0}, {y = -0, g = -0, t = -0}, {z = 0, b = 0, p = 0}}

很明显,法向量不能是零向量。这是 glm 库中所有问题的地方:

710                             v1.y * v2.y,
(gdb) p v1.y * v2.y
$6 = inf
(gdb) p v1.y
$7 = -2.65845583e+36
(gdb) p v2.y
$8 = -2.65845583e+36
(gdb) 

这似乎是溢出,但我不确定。如果是,有没有办法强制使用 glm 而不是,或者有其他方法可以解决这个问题?doublefloat

C++ 浮点 精度 GLM

评论

0赞 273K 7/10/2023
这是你对这个问题的调查的一个好故事。但是,如果您还没有发布最小的可重复示例,SO 用户如何帮助您呢?目前还不清楚那些 , , , 是什么。coordcenterv1v2
2赞 Evg 7/10/2023
鉴于实现,难怪它会溢出。您可以重新考虑您的算法以避免如此巨大的值,或者使用中间缩放重新实现此函数。v * inversesqrt(dot(v, v))
1赞 Evg 7/10/2023
看这里: github.com/gagern/gnulib/blob/master/lib/hypot.c

答:

0赞 DENIS KOVALENKO 7/10/2023 #1

就像 Evg 支持 Moderator Strike 一样,在这种情况下,我们需要规范化大值以避免溢出