问题
帧同步中一般用定点数来处理逻辑运算,那么为什么要用定点数呢?
浮点数为何不准?
参考文章:https://zhuanlan.zhihu.com/p/467157712
上面这个文章我只能读懂前面,按我的理解,意思就是说由于存在有效位数的限制会导致浮点数的运算产生误差,而且这种误差还会积累。因而使用浮点数来进行逻辑运算时,就很可能会出现客户端之间数据不一致的问题,这跟帧同步本身对客户端逻辑帧运算的结果要求一致相悖。
因而我们就需要用到定点数来保证数据运算和存储的一致,那定点数是什么呢?
定点数的定义
「定点」表示法:约定计算机中小数点的位置,且这个位置固定不变,小数点前、后的数字,分别用二进制表示。
而用这种定点表示法表示的数字,我们称之为「定点数」
定点数的精度丢失
比如十进制数1.5(D),我们用定点表示法,就表示为1.1(B)
如果要存到计算机内存中,假设为8位,我们就要约定多少位是整数,多少位是小数。
假设约定前6位为整数,后2位为小数,那么可得
000001 10
随着我们的约定改变,也就是保留多少位来作为小数,数的精度就会发生变化。
现在我们再拿一个数,例如1.5625(D),按我们的约定,
其表示为000001 10
我们可以看到,1.5是跟1.5625在二进制表示上是相等的,因而这就是精度丢失的情况。
我们如果进行运算。
可以得到结果为000011 00,将其转换回十进制数,就是3(D)。
而我们如果用浮点数运算则是1.5+1.5625 = 3.0625(这是保证浮点数精度正确的情况下的结果)
那为何还要用定点数呢?
因为这么做,我们就是通过丢失精度的做法,来确保数据的正确性。
因为按照以上约定,我们虽然使得1.565失真为1.5了,但是同时,我们确保了所有客户端上在内存中1.5和1.5625都是以000001 10的形式保存,从而在所有客户端运算这两个数的时候,结果一定是000011 00,也就是3(D)
而如果用浮点数运算,1.5+1.5625在不同的客户端上可能会存在不同的结果。
总结
定点数的作用就是让不同数量级的数都有相同的表示精度(比如上面的约定,无论你是多少大的数,一定只会保留两位作为小数部分)
综上所述,我们才要在游戏的逻辑运算部分中使用定点数。
补充
那么我们常用的将一个数乘以1000来作为定点数的方法,其实就是人为约定最后4位作为小数部分。
例如一个浮点数1234.1234567
乘以1000后并且转换为整数数据类型,那结果就是12341234,由于是整数,后面的567被截取掉了。
现在我们就可以这么看这个数 前面的1234是整数部分,后面的1234是小数部分。