是否定义了移动浮点数会发生什么?
Is it defined what will happen if you shift a float?
我正在关注 This video tutorial 来实现一个 raycaster。它包含以下代码:
if(ra > PI) { ry = (((int)py>>6)<<6)-0.0001; rx=(py-ry)*aTan+px; yo=-64; xo=-yo*aTan; }//looking up
我希望我已经正确转录了这个。特别是,我的问题是关于将 py
(它被声明为 float
)转换为整数,来回移动它,减去一些东西,然后将它分配给一个 ry
(也是一个 float
) 这行代码是在时间 7:24 输入的,他在这里也说明了他要
round the y position to the nearest 64th value
(我不确定这是否意味着最接近的64的倍数或最接近的(1/64),但我知道源中的6是从数字64派生的,即2⁶)
一方面,我认为编译器将 32 位浮点数加载(比如说)到机器寄存器中,然后将该值向下移动六个空格,然后再向上移动是有效的六个空格(这两个操作可能会干扰尾数,或指数,或者其他东西,或这两个操作可以通过窥孔优化步骤删除。)
另外我认为编译器在执行此语句时让恶魔飞出你的鼻子是有效的。
所以我的问题是,当 py
是 float
时,是否在 C 中定义了 (((int)py>>6)<<6)
?
该代码不会移位 float
,因为没有为浮点类型定义移位运算符。如果你尝试它,你会得到一个编译器错误。
注意代码是 (int)py >> 6
,float
在移位操作之前转换为 int
。整数值是正在移动的值。
如果您的问题是 "what will happen if you shift a float?",答案是无法编译。 Example on Compiler Explorer.
is (((int)py>>6)<<6)
defined in C when py
is float
?
对于许多 float
来说,这肯定是 未定义的行为 (UB)。 int
的强制转换为 float
的 UB,其整数值超出 [INT_MIN ... INT_MAX]
范围。
因此,所有 typical float
- the large valued ones, NaN 和无穷大的大约 38% 的代码是 UB。
对于典型的 float
,几乎所有 float
.
都定义了转换为 int128_t
为了达到 OP 的目标,代码可以使用下面的代码,我相信它对所有 float
.
都有很好的定义
如果有的话,请使用下面的内容来评估一个人编写的代码.
的正确性
// round the y position to the nearest 64th value
float round_to_64th(float x) {
if (isfinite(x)) {
float ipart;
// The modf functions break the argument value into integral and fractional parts
float frac = modff(x, &ipart);
x = ipart + roundf(frac*64)/64;
}
return x;
}
"I'm unsure if that means the nearest multiple of 64 or the nearest (1/64)"
经过审查,OP 的代码正试图截断到最接近的 64 或 2⁶ 的倍数。
对于许多 float
来说仍然是 UB。
我正在关注 This video tutorial 来实现一个 raycaster。它包含以下代码:
if(ra > PI) { ry = (((int)py>>6)<<6)-0.0001; rx=(py-ry)*aTan+px; yo=-64; xo=-yo*aTan; }//looking up
我希望我已经正确转录了这个。特别是,我的问题是关于将 py
(它被声明为 float
)转换为整数,来回移动它,减去一些东西,然后将它分配给一个 ry
(也是一个 float
) 这行代码是在时间 7:24 输入的,他在这里也说明了他要
round the y position to the nearest 64th value
(我不确定这是否意味着最接近的64的倍数或最接近的(1/64),但我知道源中的6是从数字64派生的,即2⁶)
一方面,我认为编译器将 32 位浮点数加载(比如说)到机器寄存器中,然后将该值向下移动六个空格,然后再向上移动是有效的六个空格(这两个操作可能会干扰尾数,或指数,或者其他东西,或这两个操作可以通过窥孔优化步骤删除。)
另外我认为编译器在执行此语句时让恶魔飞出你的鼻子是有效的。
所以我的问题是,当 py
是 float
时,是否在 C 中定义了 (((int)py>>6)<<6)
?
该代码不会移位 float
,因为没有为浮点类型定义移位运算符。如果你尝试它,你会得到一个编译器错误。
注意代码是 (int)py >> 6
,float
在移位操作之前转换为 int
。整数值是正在移动的值。
如果您的问题是 "what will happen if you shift a float?",答案是无法编译。 Example on Compiler Explorer.
is
(((int)py>>6)<<6)
defined in C whenpy
isfloat
?
对于许多 float
来说,这肯定是 未定义的行为 (UB)。 int
的强制转换为 float
的 UB,其整数值超出 [INT_MIN ... INT_MAX]
范围。
因此,所有 typical float
- the large valued ones, NaN 和无穷大的大约 38% 的代码是 UB。
对于典型的 float
,几乎所有 float
.
int128_t
为了达到 OP 的目标,代码可以使用下面的代码,我相信它对所有 float
.
如果有的话,请使用下面的内容来评估一个人编写的代码.
的正确性// round the y position to the nearest 64th value
float round_to_64th(float x) {
if (isfinite(x)) {
float ipart;
// The modf functions break the argument value into integral and fractional parts
float frac = modff(x, &ipart);
x = ipart + roundf(frac*64)/64;
}
return x;
}
"I'm unsure if that means the nearest multiple of 64 or the nearest (1/64)"
经过审查,OP 的代码正试图截断到最接近的 64 或 2⁶ 的倍数。
对于许多 float
来说仍然是 UB。