【发布时间】:2015-02-01 15:20:29
【问题描述】:
我发现这段代码可以得到平方根,令我惊讶的是它使用联合和位移的方式,这就是代码:
float sqrt3(const float x)
{
union
{
int i;
float x;
} u;
u.x = x;
u.i = (1<<29) + (u.i >> 1) - (1<<22);
return u.x;
}
首先将 x 的值保存在 u.x 中,然后将值赋给 u.i 然后是数字的平方根并神奇地出现u.x
¿有人向我解释一下这个算法是如何实现的?
【问题讨论】:
-
它不会返回数字的平方根。
-
好吧,首先这段代码表现出 UB(未定义行为),因此不应该信任它可以在任何平台上工作。但其次,您可能值得阅读 IEEE 754 binary32 浮点格式;特别是,它将 32 位
float分为 1 个符号位、8 个指数位和 23 个尾数位,因此sign* 1.mantissa * pow(2, exponent-127)您的代码所做的就是将指数部分减半并损坏尾数。这样做是因为数字的平方根有一个大约一半大小的指数(例如 4000000 ~ 10^6、4000 ~ 10^3,指数减半)。 -
返回平方根我想知道它是如何工作的
-
@Iwillnotexist Idonotexist : 因为这有未定义的行为