10
float length =  32.32f;
long  i = *(long*)&length ; // casting a float pointer to a long pointer...
i >>= 1; // right shift i but 1 ... or div by 2
length = *(float*)&i; // is this necessary?

打印长度给出:0.0

最终结果应该是:16.16;

这个想法来自http://en.wikipedia.org/wiki/Fast_inverse_square_root。我试图理解代码的部分是取出浮点数中的长并对其执行按位运算。我猜重点是通过避免分支来提高性能?

上面的代码失败了。谁能告诉我我做错了什么?我的印象是,将long存储放入 a 中float并对其进行操作很简单,这是错误的吗?

我发现了一些有趣的东西,如果我将代码更改为:

 float length =  32.32f;
 long  i = *(long*)&length ;
 i  = 0x5f3759df - ( i >> 1 ); 
 length = *(float*)&i;

将此数字(0x5f3759df)添加到组合中。

打印出长度 * 100 给出:17.0538 // 16.16 的近似值
尝试使用不同的长度给出相同的结果。

例如:长度 = 100;结果是:10.3299?? // 几乎...

4

1 回答 1

16

32.32f 的二进制是01000010000000010100011110101110.

换班后:00100001000000001010001111010111

您可以从Wikipedia查看浮点数是如何存储的。

标志:0

exp:01000010=66

尾数:00000001010001111010111=2 -7(左右)

所以结果 = 2 (66-127) *(1+2 -7 )=2 -59 (左右)

它不是零。如果您使用printf("%.40f\n",x2);,那么您将看到它。

如果您对神奇数字为何起作用感到奇怪:您可以仔细阅读 wiki 页面或阅读本文

于 2013-06-04T00:59:11.250 回答