365health-365体育投注网站官网-365bet官网投注

4.第二阶段x86游戏实战2-CE加强修改移动速度(浮点数存放方式与转换)

4.第二阶段x86游戏实战2-CE加强修改移动速度(浮点数存放方式与转换)

浮点型有单浮点(单位是float)、双浮点(单位是double),然后单浮点和双浮点都是小数,单浮点是4字节小数、双浮点是8字节小数,可以看出双浮点比单浮点表示的小数范围大,所以它俩的区别就是可以表示的数值范围不一样

然后浮点数的二进制转十进制或十六进制有点复杂现在不容易写明白,不过浮点数的二进制转十进制或十六进制不知道怎么转的也没事,对于逆向没有影响,因为CE这种工具都给转换好了,不需要我们自己转换

浮点数转换方式:

0 01111110 00000000000000000000000 这个二进制是0.5的二进制,然后怎么把二进制算成0.5的?为了防止看着头疼,公式就不写了,直接上傻瓜模式,如下图,小数在计算机中的存储方式,可以看出它分成了三段,这是以 IEEE 754标准存放的浮点数(小数)数据,计算机中常用的浮点数存储标准就是IEEE 754标准

三段分别的意思,下图红框圈出来的位(这些数是二进制数,一个二进制数的单位是位)它的值是1表示负数0表示正数,说它们是三段为什么只圈出了最左边的第一位?因为剩下的两段的名字不直观看了会蒙,为了遵循傻瓜模式指定不能让人看蒙了所以直接不写,直接继续看下方的例子

要注意虽然是遵循傻瓜模式但是不会 加乘除就没办法了,可以直接放弃,不要关注浮点数和二进制怎么转的了,使用CE这种工具给你转吧,不用钻牛角尖,知道怎么转的用处也不大。

如下图以单浮点为例,下图第二段也就是红框圈出来的这一段,首先把二进制是1的全部进行相加结果是2+4+8+16+32+64 = 126,然后下图圈出来一共有8位,然后就是2的7次方也就是2乘2乘2乘2乘2乘2乘2-1=127也就是7个2相乘然后减1的结果,然后用126-127=负1,然后就是2的负1次方也就是1除2=0.5,0.5就这样得到的

然后上面是一个简单的例子在看0.6的,0.6二进制是0 01111110 00110011001100110011010 可以看到它从左边数第三段有1有0了,这种怎么算?然后第二段与0.5一样所以第二段的结果也是0.5,所以就只剩下计算第三部分就可以了,如下图0.5是2的-1次方也就是1除以2等于0.5,0.25是2的-2次方也就是1除以2除以2=0.25其它的都是同理,它最后几位普通的计算器根本无法计算了,后几位是通过AI计算的,AI最后一位也计算不了了,然后最后一位粗略的值0.000000119209

然后把二进制的值是1的拿出来相加最终的结果是0.2000000476837158,得到这个结果之后对它进行加1,为什么加1?IEEE 754标准(或者说是规则)它规定了就得加1(实际上是加2的0次方,2的0次方的结果也是1),加完1之后的结果是1.2000000476837158,然后0.5乘1.2000000476837158结果就是0.6

计算的结果,然后可以看到下图红框0.6后面还有一堆数字,这是正常现象,计算机中的浮点数就是存在这种问题,这个问题叫做精度问题,所以在使用浮点数的时候要注意,高级语言都有专门处理浮点数的函数(直接百度搜C++精度问题这种关键字就能找到)可以避免精度问题

上方是通过IEEE 754标准进行二进制转浮点数的方式,然后浮点数转二进制,以 251.62 这个数为例子,首先251的二进制是11111011,也就是 1+2+8+16+32+64+128=251,然后0.62的二进制它需要计算0.62乘以2直到乘到整数为止,但是计算机有宽度单浮点只有23位,如果是循环小数最多只能乘23次2,多了计算机没法存放,然后开始计算

0.62乘以2结果是1.24,然后二进制取整数位也就是1

然后上方把1拿了出来所以就是0.24乘以2,结果是0.48,然后把0拿出来,现在的二进制是10

然后是0.48乘以2,结果是0.96,然后把0拿出来,现在的二进制是100

然后0.96乘以2,结果是1.92,然后把1拿出来,现在的二进制是1001

然后上面把1拿了出来所以就是0.92乘以2,结果是1.84,然后把1拿出来,现在的二进制是10011

然后0.84乘以2,结果是1.68,然后把1拿出来,现在的二进制是10011

然后0.68乘以2,结果是1.36,然后把1拿出来,现在的二进制是100111,然后0.62不能精确表示一个有限的二进制小数,所以就取到100111,不信的可以继续往下乘以2

然后251.62的二进制就是11111011.100111,这个11111011.100111是251.62的二进制表示法并不是计算机存储的那个,计算机存放浮点数是遵循的IEEE 754标准,所以要把11111011.100111转成IEEE 754标准,转换方式

首先把11111011.100111变成1.1111011100111这样的,也就是小数点往前移动,一直移动到左边剩1位,然后小数点移动了7位,然后127+7(移动几位就加几)得到134,这个134的二进制是10000110,这就是第二部分,第三部分11110111001110000000000(23位,不够23位往后面补0),超过23位计算机没法存(现在的计算机可以存,用双浮点就可以存了,如果双浮点是52位不够52位就补0),最终的二进制是0 10000110 11110111001110000000000

以单浮点IEEE 754标准为例:

符号位:0(正数)

质数位:10000110

尾数位:11110111001110000000000

质数位说的就是第二部分、尾数位说的就是第三部分,这俩词很抽象很难理解直接忽略

补充:

0.5转二进制的转法,上面写了小数部分乘以2,0.5乘以2等于1,然后二进制就是0.1,上面通过往左移动小数点的次数对127进行相加得到了第二部分,这种只有1位的怎么移动?这里记住0就是127-1=126所以第二部分的二进制是01111110,第三部分,0.5的二进制是0.1,这个1根据IEEE 754标准它会隐藏,所以0.5第三部分的二进制是00000000000000000000000也就是23个0,只要二进制是0.几的默认把后面第一个1隐藏变成0就可以了

相关推荐