/cfixed32

32位定点数运算

Primary LanguageC++

定点数计算

使用定点数,可以使用整数运算和位运算代替浮点数运算,以提升运算速度。

提供C风格的宏定义方式和C++风格的运算符重载方式。


BENCHMARK

进行10000000次+-*/混合运算,对比float类型和定点数类型计算速度。(gcc9编译器,O1优化,intel-i7。详见benchmark.cpp和CMakeLists.txt)

float类型耗时:30.1ms

定点数类型耗时:6.9ms

PS:如果使用C++风格的方式,由于有函数调用的中间变量,需要至少使用O1编译优化,否则会比float类型计算速度还慢。


定点数是一种用整数表示小数的方式,即:实际值=存储值/缩放倍率。由于除以2的次幂等同于右移相应位数,且移位运算比乘法快,所以实际使用定点数时通常使得缩放倍率为2的次幂。

设v表示实际值;x表示存储值;p表示缩放倍率2的次幂。即:

v1=x1/2^p=x1>>p

v2=x2/2^p=x2>>p

1.定点数加减法

v3=v1±v2=(x1±x2)/2^p

故x3=x1±x2

从公式可见,定点数加减法可以直接使用整数的加减法

2.定点数乘法

v3=v1*v2=(x1*x2/2^p)/2^p

故x3=x1*x2/2^p=x1*x2>>p

从公式可见,定点数乘法可以先做整数乘法,再进行移位。注意:在做整数乘法时,很可能发生上溢出的现象导致结果错误,所以在进行整数乘法前,需要首先对整数精度进行扩增。如原本是int32_t则需要转成int64_t再进行乘法运算。

3.定点数除法

v3=v1/v2=x1/x2=(x1/x2*2^p)/2^p

故x3=x1/x2*2^p=x1/x2<<p

从公式可见,定点数除法可以先做整数除法,再进行移位。注意:在做整数除法时,由于会取整,将大量丢失精度。所以将移位操作提前,即先对被除数进行移位运算,再做除法。注意到移位运算同样可能发生上溢出,所以也需要首先对整数精度进行扩增。