浮点数的操作问题

浮点数的表示

float Q_rsqrt( float number )
{
	long i;
	float x2, y;
	const float threehalfs = 1.5F;

	x2 = number * 0.5F;
	y  = number;
	i  = * ( long * ) &y;                       // evil floating point bit level hacking
	i  = 0x5f3759df - ( i >> 1 );               // what the fuck? 
	y  = * ( float * ) &i;
	y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
//	y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed

	return y;
}

这是 wiki 上的快速倒开方算法,非常神奇,但是阅读时发现

i = *(long*)&y

从这一句开始就开始有点懵逼了,由于个人能力的局限性,这里不打算深究整个算法的实现原理,而是打算从这一句代码去搞清楚计算机中的浮点数存储表示。


浮点数的二进制转换

	float f = 0.15625;
	int i = *(int*)&f;
	printf("%d\n", i);

从这个例子出发,[1]首先定义了一个浮点数f = 0.15625,[2]中将f 的4个字节的内存地址转换成整型,[3]中将转换后的整型结果打印出来,结果是1042284544。
首先,单精度的具体定义可参考wiki,下面使用S表示符号位SignE 表示指数ExponentM表示有效精度Significand precision。对于32bit 的浮点数而言,第31位表示符号位,30-23位表示指数,剩下的第23-0位表示有效精度。回到[1],这里的f = 0.15625,首先要转换成二进制:

0.15625 < 2 − 1 2^{-1} 21 = 0.5,所以第一位置0,得到0.0
0.15625 < 2 − 2 2^{-2} 22 = 0.25,第二位置0,得到0.00
0.15625 > 2 − 3 2^{-3} 23 = 0.125,第三位置1,得到0.001
0.15625 - 0.125 = 0.03125 < 2 − 4 2^{-4} 24 = 0.0625,第四位置0,得到0.0010
0.03125 = 2 − 5 2^{-5} 25,第五位置1,得到0.00101
所以 0.125 6 10 0.1256_{10} 0.125610 = 0.0010 1 2 0.00101_{2} 0.001012,整数部分按照正常二进制转换即可。

###浮点数表示
0.125 6 10 0.1256_{10} 0.125610 转换成二进制 0.0010 1 2 0.00101_{2} 0.001012 后,先转换成1.01 * 2 − 3 2^{-3} 23,指数位的表示因为是使用偏移值表示,所以这里需要加上偏移值127,即-3 + 127 = 124,二进制表示为 0111110 0 2 01111100_{2} 011111002,在浮点数的表示中,通常会省略最前面的1(需考虑其他情况时可以先参考这篇博客),有效数字为小数点后的数字,这里是01。
最后,回到最开始的存储表示:

0.15625为正数,符号位S 为0
指数位是124,二进制表示为 0111110 0 2 01111100_{2} 011111002,即E 为01111100
有效精度的数字表示为01,补足23位得到M为01000000000000000000000
最后得到内存中的二进制表示 00111110001000000000000000000000

结果

0.15625在内存中的的表示为00111110001000000000000000000000,当由[2]指定将这段内存的数据以整形的方式读取出来时,就会直接做二进制到十进制的变换,所以打印出来的就是1042284544。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值