是否定义了移动浮点数会发生什么?

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 位浮点数加载(比如说)到机器寄存器中,然后将该值向下移动六个空格,然后再向上移动是有效的六个空格(这两个操作可能会干扰尾数,或指数,或者其他东西,这两个操作可以通过窥孔优化步骤删除。)

另外我认为编译器在执行此语句时让恶魔飞出你的鼻子是有效的。

所以我的问题是,当 pyfloat 时,是否在 C 中定义了 (((int)py>>6)<<6)

该代码不会移位 float,因为没有为浮点类型定义移位运算符。如果你尝试它,你会得到一个编译器错误。

注意代码是 (int)py >> 6float 在移位操作之前转换为 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。