为什么此 C 代码中使用的 IEEE-754 指数偏差是 126.94269504 而不是 127?
Why the IEEE-754 exponent bias used in this C code is 126.94269504 instead of 127?
以下 C 函数来自 fastapprox 项目。
static inline float
fasterlog2 (float x)
{
union { float f; uint32_t i; } vx = { x };
float y = vx.i;
y *= 1.1920928955078125e-7f;
return y - 126.94269504f;
}
这里有专家能解释一下为什么上面代码中使用的指数偏差是126.94269504而不是127吗?是不是更准确的偏差值?
嗯,不,126.94269504 不是 "more accurate" 偏差值。这段代码正在做一些非常非常奇怪的事情;我很惊讶它能起作用。它将 float 的位当作 int(根据我的经验,这通常会给你一个完全垃圾的值,但也许不是),然后获取 "garbage" int 值并将其转换回 float,然后对它做一些数学运算。正如他们所说,这是一种快速且近似的做某事的方法,在本例中,采用 base-2 日志。它根本不应该工作,但 127 和 126.94269504 之间的差异显然只是几个愚蠢的软糖因素之一,这些因素旨在从应该是无意义的代码中挽救一些意义。 (有点像 "two almost wrongs make an almost-right" 之类的东西。)
如果您想准确提取浮点数的尾数和指数(尽管这既不会那么快也不会那么近似),通常的方法是使用 frexpf
函数。
在您链接的项目中,他们包含了一个 Mathematica notebook 及其算法的解释,其中包括 "mysterious" -126.94269
值。
如果您需要查看器,可以从 Mathematica website 免费获得一个。
编辑:既然我觉得慷慨,这里是相关部分in screenshot form。
简单的说,他们解释的值是"simpler, faster, and less accurate".
他们没有使用 -126.94269
代替 -127
,而是使用它代替以下计算的结果(为简洁起见四舍五入的值):
-124.2255 - 1.498 * mx - (1.72588 / (0.35201 + mx))
以下 C 函数来自 fastapprox 项目。
static inline float
fasterlog2 (float x)
{
union { float f; uint32_t i; } vx = { x };
float y = vx.i;
y *= 1.1920928955078125e-7f;
return y - 126.94269504f;
}
这里有专家能解释一下为什么上面代码中使用的指数偏差是126.94269504而不是127吗?是不是更准确的偏差值?
嗯,不,126.94269504 不是 "more accurate" 偏差值。这段代码正在做一些非常非常奇怪的事情;我很惊讶它能起作用。它将 float 的位当作 int(根据我的经验,这通常会给你一个完全垃圾的值,但也许不是),然后获取 "garbage" int 值并将其转换回 float,然后对它做一些数学运算。正如他们所说,这是一种快速且近似的做某事的方法,在本例中,采用 base-2 日志。它根本不应该工作,但 127 和 126.94269504 之间的差异显然只是几个愚蠢的软糖因素之一,这些因素旨在从应该是无意义的代码中挽救一些意义。 (有点像 "two almost wrongs make an almost-right" 之类的东西。)
如果您想准确提取浮点数的尾数和指数(尽管这既不会那么快也不会那么近似),通常的方法是使用 frexpf
函数。
在您链接的项目中,他们包含了一个 Mathematica notebook 及其算法的解释,其中包括 "mysterious" -126.94269
值。
如果您需要查看器,可以从 Mathematica website 免费获得一个。
编辑:既然我觉得慷慨,这里是相关部分in screenshot form。
简单的说,他们解释的值是"simpler, faster, and less accurate".
他们没有使用 -126.94269
代替 -127
,而是使用它代替以下计算的结果(为简洁起见四舍五入的值):
-124.2255 - 1.498 * mx - (1.72588 / (0.35201 + mx))