使用Q格式的目的:加快运算速度,CPU计算整数比浮点方便迅速 提高运算精度
例如:两个小数相乘0.123*0.456,可以先将二者各乘以1000倍,变成123*456,方便CPU计算。算完之后,再将结果除以1000000,就是真实的结果了。
假设Q16定点算法,就是0.123*2^16*0.456*2^16,将两个数同时扩大2^16倍,算完之后,再除回去。为什么要2^16而不是乘以1000呢?因为以2为基数的乘除法在CPU里通过移位完成,相当迅速。不过实际应用的时候还要考虑溢出,余数效应等影响。
样例说明:
设x=0.5 y=3.1 则浮点运算的结果为z=x+y=0.5+3.1=3.6
x=0.5*2^15=16384//Q15定标
y=3.1*2^13≈25395//Q13定标
temp=25395<<2=101580//左移两把y扩大到相同的标尺上进行运行,统一单位进行运算。
temp=x+temp=16384+101580=117964
z=(int)(117964L>>2)=29491//结果用Q13表示
因为z的Q为13,所以定点值z=29491即为z=29491/2^13≈3.59998≈3.6//精度高
同样是上面的运算,用Q4定标计算
Qx=4 //Q4表示的范围-2048<=X<=2048-1/16,精度为1/16
Qy=4
Qz=4
x=0.5*2^4=8
y=3.1*16≈50
temp=8+50=58
z=58/16=3.625≈3.6//精度低
下表提供了各种 IQ 格式的特征(C 数据类型、整数位数、小数位数、可表示的最小负值、可表示的最大正值和可表示的最小差值):
类型 | 整数位数 | 小数位数 | 最小范围 | 最大范围 | 分辨率 |
---|---|---|---|---|---|
_iq30 | 2 | 30 | -2 | 1.999 999 999 | 0.000 000 001 |
_iq29 | 3 | 29 | -4 | 3.999 999 998 | 0.000 000 002 |
_iq28 | 4 | 28 | -8 | 7.999 999 996 | 0.000 000 004 |
_iq27 | 5 | 27 | -16 | 15.999 999 993 | 0.000 000 007 |
_iq26 | 6 | 26 | -32 | 31.999 999 985 | 0.000 000 015 |
_iq25 | 7 | 25 | -64 | 63.999 999 970 | 0.000 000 030 |
_iq24 | 8 | 24 | -128 | 127.999 999 940 | 0.000 000 060 |
_iq23 | 9 | 23 | -256 | 255.999 999 881 | 0.000 000 119 |
_iq22 | 10 | 22 | -512 | 511.999 999 762 | 0.000 000 238 |
_iq21 | 11 | 21 | -1,024 | 1,023.999 999 523 | 0.000 000 477 |
_iq20 | 12 | 20 | -2,048 | 2,047.999 999 046 | 0.000 000 954 |
_iq19 | 13 | 19 | -4,096 | 4,095.999 998 093 | 0.000 001 907 |
_iq18 | 14 | 18 | -8,192 | 8,191.999 996 185 | 0.000 003 815 |
_iq17 | 15 | 17 | -16,384 | 16,383.999 992 371 | 0.000 007 629 |
_iq16 | 16 | 16 | -32,768 | 32,767.999 984 741 | 0.000 015 259 |
_iq15 | 17 | 15 | -65,536 | 65,535.999 969 483 | 0.000 030 518 |
_iq14 | 18 | 14 | -131,072 | 131,071.999 938 965 | 0.000 061 035 |
_iq13 | 19 | 13 | -262,144 | 262,143.999 877 930 | 0.000 122 070 |
_iq12 | 20 | 12 | -524,288 | 524,287.999 755 859 | 0.000 244 141 |
_iq11 | 21 | 11 | -1,048,576 | 1,048,575.999 511 720 | 0.000 488 281 |
_iq10 | 22 | 10 | -2,097,152 | 2,097,151.999 023 440 | 0.000 976 563 |
_iq9 | 23 | 9 | -4,194,304 | 4,194,303.998 046 880 | 0.001 953 125 |
_iq8 | 24 | 8 | -8,388,608 | 8,388,607.996 093 750 | 0.003 906 250 |
_iq7 | 25 | 7 | -16,777,216 | 16,777,215.992 187 500 | 0.007 812 500 |
_iq6 | 26 | 6 | -33,554,432 | 33,554,431.984 375 000 | 0.015 625 000 |
_iq5 | 27 | 5 | -67,108,864 | 67,108,863.968 750 000 | 0.031 250 000 |
_iq4 | 28 | 4 | -134,217,728 | 134,217,727.937 500 000 | 0.062 500 000 |
_iq3 | 29 | 3 | -268,435,456 | 268,435,455.875 000 000 | 0.125 000 000 |
_iq2 | 30 | 2 | -536,870,912 | 536,870,911.750 000 000 | 0.250 000 000 |
_iq1 | 31 | 1 | -1,073,741,824 | 1,073,741,823.500 000 000 | 0.500 000 000 |