0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Q格式的表示方式以及相应的运算

我快闭嘴 来源:小麦大叔 作者:小麦大叔 2022-09-23 15:20 次阅读

用过DSP的应该都知道Q格式吧;

  • 1 前言

  • 2 Q数据的表示

    • 2.1 范围和精度

    • 2.2 推导

  • 3 Q数据的运算

    • 3.1 0x7FFF

    • 3.2 0x8000

    • 3.3 加法

    • 3.4 减法

    • 3.5 乘法

    • 3.6 除法

  • 4 常见Q格式的数据范围

  • 5 0x5f3759df

  • 6 总结

1 前言

Q格式是二进制的定点数格式,相对于浮点数,Q格式指定了相应的小数位数和整数位数,在没有浮点运算的平台上,可以更快地对浮点数据进行处理,以及应用在需要恒定分辨率的程序中(浮点数的精度是会变化的);
需要注意的是Q格式是概念上小数定点,通过选择常规的二进制数整数位数和小数位数,从而达到所需要的数值范围和精度,这里可能有点抽象,下面继续看介绍。

2 Q数据的表示

2.1 范围和精度

定点数通常表示为,其中m为整数个数,n为小数个数,其中最高位位符号位并且以二进制补码的形式存储;

  • 范围:
  • 精度:

无符号的用表示;

  • 范围:
  • 精度:

2.2 推导

无符号Q格式数据的推导这里以一个16位无符号整数为例,所能表示的最大数据的二进制形式如下图所示;

425afab4-3a80-11ed-9e49-dac502259ad0.png

所以不难看出,的范围大小和精度;根据等比数列求和公式得到,整数域最大值如下:

小数域最大值如下:

因此的范围满足 ;

有符号Q格式数据的推导这里以一个16位有符号整数为例,所能表示的最大数据的二进制形式如下图所示;

426c1362-3a80-11ed-9e49-dac502259ad0.png

所以不难求出,的范围大小和精度;根据等比数列求和公式得到,整数域最大值如下:

小数域最大值如下:

因此最大能表示的数为:;

所能表示的最小数据的二进制形式如下图所示;

428a142a-3a80-11ed-9e49-dac502259ad0.png

可以从图中看到,该数表示为;

补充一下:负数在计算机中是补码的形式存在的,补码=反码+1,符号位为1则表示为负数;
那么-4该如何表示呢?
8 bit数据为例,如下所示;
原码:0B 0000 100
反码:0B 1111 011
补码:0B 1111 100

综上,可以得到有符号的范围是:

3 Q数据的运算

3.1 0x7FFF

最大数的十六进制为0x7FFF,如下图所示;

426c1362-3a80-11ed-9e49-dac502259ad0.png

3.2 0x8000

最小数的十六进制为0X8000,如下图所示;

428a142a-3a80-11ed-9e49-dac502259ad0.png

上述这两种情况,下面都会用到。

3.3 加法

加法和减法需要两个Q格式的数据定标相同,即和满足以下条件;

int16_tq_add(int16_ta,int16_tb)
{
returna+b;
}

上面的程序其实并不安全,在一般的DSP芯片具有防止溢出的指令,但是通常需要做一下溢出检测,具体如下所示;

//https://great.blog.csdn.net/
int16_tq_add_sat(int16_ta,int16_tb)
{
int16_tresult;
int32_ttmp;

tmp=(int32_t)a+(int32_t)b;
if(tmp>0x7FFF)
tmp=0x7FFF;
if(tmp< -1*0x8000)
tmp=-1*0x8000;
result=(int16_t)tmp;

returnresult;
}

3.4 减法

类似于加法的操作,需要相同定标的两个Q格式数进行相减,但是不会存在溢出的情况;

//https://great.blog.csdn.net/
int16_tq_sub(int16_ta,int16_tb)
{
returna-b;
}

3.5 乘法

乘法同样需要考虑溢出的问题,这里通过sat16函数,对溢出做了处理;

//https://great.blog.csdn.net/
//precomputedvalue:
#defineK(1<< (Q - 1))

//saturatetorangeofint16_t
int16_tsat16(int32_tx)
{
if(x>0x7FFF)return0x7FFF;
elseif(x< -0x8000)return-0x8000;
elsereturn(int16_t)x;
}

int16_tq_mul(int16_ta,int16_tb)
{
int16_tresult;
int32_ttemp;

temp=(int32_t)a*(int32_t)b;//resulttypeisoperand'stype
//Rounding;midvaluesareroundedup
temp+=K;
//Correctbydividingbybaseandsaturateresult
result=sat16(temp>>Q);

returnresult;
}

3.6 除法

//https://great.blog.csdn.net/
int16_tq_div(int16_ta,int16_tb)
{
/*pre-multiplybythebase(UpscaletoQ16sothattheresultwillbeinQ8format)*/
int32_ttemp=(int32_t)a<< Q;
    /*Rounding:midvaluesareroundedup(downfornegativevalues).*/
/*ORcomparemostsignificantbitsi.e.if(((temp>>31)&1)==((b>>15)&1))*/
if((temp>=0&&b>=0)||(temp< 0&&b< 0)){
temp+=b/2;/*ORshift1biti.e.temp+=(b>>1);*/
}else{
temp-=b/2;/*ORshift1biti.e.temp-=(b>>1);*/
}
return(int16_t)(temp/b);
}

4 常见Q格式的数据范围

定点数和浮点数转换的关系满足以下公式:

其中为,m表示整数位数,n表示小数位数;

#include
#include
#include


intmain()
{
//0111111111111111
int16_tq_max=32767;//0x7FFF
//1000000000000000
int16_tq_min=-32768;//0x8000
floatf_max=0;
floatf_min=0;
printf("
");
for(int8_ti=15;i>=0;i--){
f_max=(float)q_max/pow(2,i);
f_min=(float)q_min/pow(2,i);

printf("	|Q%d|Q%d.%d|%f|%f|
",
i,(15-i),i,f_max,f_min);
}

return0;
}

运行得到结果如下所示;42d1c5f4-3a80-11ed-9e49-dac502259ad0.png

Q Qmn Max Min
Q 15 Q 0.15 0.999969 -1.000000
Q 14 Q 1.14 1.999939 -2.000000
Q 13 Q 2.13 3.999878 -4.000000
Q 12 Q 3.12 7.999756 -8.000000
Q 11 Q 4.11 15.999512 -16.000000
Q 10 Q 5.10 31.999023 -32.000000
Q 9 Q 6.9 63.998047 -64.000000
Q 8 Q 7.8 127.996094 -128.000000
Q 7 Q 8.7 255.992188 -256.000000
Q 6 Q 9.6 511.984375 -512.000000
Q 5 Q 10.5 1023.968750 -1024.000000
Q 4 Q 11.4 2047.937500 -2048.000000
Q 3 Q 12.3 4095.875000 -4096.000000
Q 2 Q 13.2 8191.750000 -8192.000000
Q 1 Q 14.1 16383.500000 -16384.000000
Q 0 Q 15.0 32767.000000 -32768.000000

5 0x5f3759df

Q格式虽然十分抽象,但是且看看这个数字0x5f3759df,感觉和Q格式有某种联系,它是雷神之锤3中的一个算法的魔数,毕竟游戏引擎需要充分考虑到效率,具体的由来可以看一下论文《Fast Inverse Square Root》,下面是源码中剥出来的快速平方根算法;

floatQ_rsqrt(floatnumber)
{
longi;
floatx2,y;
constfloatthreehalfs=1.5F;

x2=number*0.5F;
y=number;
i=*(long*)&y;//evilfloatingpointbitlevelhacking
i=0x5f3759df-(i>>1);//whatthefuck?
y=*(float*)&i;
y=y*(threehalfs-(x2*y*y));//1stiteration
//y=y*(threehalfs-(x2*y*y));//2nditeration,thiscanberemoved

#ifndefQ3_VM
#ifdef__linux__
assert(!isnan(y));//bk010122-FPE?
#endif
#endif
returny;
}

6 总结

本文介绍了Q格式的表示方式以及相应的运算,另外需要注意在Q格式运算的时候,两者定标必须相同,对于数据的溢出检测也要做相应的处理。

审核编辑:汤梓红


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • dsp
    dsp
    +关注

    关注

    544

    文章

    7682

    浏览量

    344356
  • 二进制
    +关注

    关注

    2

    文章

    705

    浏览量

    41248
  • Q格式
    +关注

    关注

    0

    文章

    2

    浏览量

    1560

原文标题:浮点运算耗时,那试试定点运算~(C语言的Q格式)

文章出处:【微信号:嵌入式情报局,微信公众号:嵌入式情报局】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    FPGA中使用FP16格式的点积运算实例分析

    本文讲述的是使用FP16格式的点积运算实例,展示了MLP72支持的数字类型和乘数的范围。
    发表于 08-15 09:50 2080次阅读
    FPGA中使用FP16<b class='flag-5'>格式</b>的点积<b class='flag-5'>运算</b>实例分析

    MATLAB矩阵及其数值运算

    。(4)rem与mod函数的区别。rem(x,y)和mod(x,y)要求x,y必须为相同大小的实矩阵或为标量。 数据的输出格式MATLAB用十进制数表示一个常数,具体可采用日常记数法和科学记数法两种表示
    发表于 05-10 10:16

    Q格式计算

    表示负的最小值为1_111.1111 1111 1111 1111 1111 1111 1111|| |符号 整数小数算的的Q28格式的下限不就应该是-7.999 999 996么?我这样理解的错误在哪里啊?
    发表于 08-19 06:43

    请问Q格式Q0格式是不是一样的东西?

    Q格式Q0格式,是不是一样的东西?
    发表于 10-11 15:07

    请问不同Q格式的用这个相乘怎么理解??

    Q21格式的,后面是Q15格式,看IQMath文档_IQmpy是两个Q格式相同的数相乘的,请问
    发表于 11-22 09:59

    请问如何理解脉冲格式表示的转子电角速度?

    FOC库中,电机转子的电角速度用脉冲格式表示,什么意思
    发表于 05-09 22:14

    Q格式相乘问题怎么解决

    );v.BaseRpm为Q0格式v.Speed为Q15格式,他两个相乘为什么得到Q0格式的v.S
    发表于 05-19 10:34

    音频信号在AIC3106和McASP之间的传递格式只能是Q15定点表示吗?

    TI工程师您好,现在用OMAPL137做音频信号处理,有两个问题:1)想问一下音频信号在AIC3106和McASP之间的传递格式只能是Q15定点表示吗?我之前用浮点数试了一下不行。2)接收到的音频
    发表于 05-22 08:00

    F28335的Q30格式有几位有效数字?

    有人用过q格式定点运算吗,为什么我转换的数不准?比如_IQ30(-1.903162068687379),结果是-1.903162122;按照官方文档,应该有10位有效数字,为什么我的只有7位 ?请各路大神各显神通,感激不尽!
    发表于 07-25 11:31

    请问为什么DSP需要Q格式q31、q15、q7和f32是什么意思?

    为什么DSP(数字信号处理)需要Q格式q31、q15、q7和f32是什么意思?
    发表于 12-17 07:56

    晶体管如何表示0和1

    通与截止这两种状态对外可以使用b极电压的相对高低来表示,进而说明了我们可以使用高电平或者低电平状态来表示二进制。也就是说b极是一个输入量(自变量),可以作为变量存储两个数值:高电平或低电平,相应的输出值
    发表于 01-13 16:23

    DSP的Q格式是什么

    用过DSP的应该都知道Q格式吧;
    发表于 07-28 09:02

    读卡器的安装方式/支持闪存格式

    读卡器的安装方式/支持闪存格式 读卡器的安装方式              安装
    发表于 01-09 15:07 1006次阅读

    由输入端选择运算方式的加、减法运算电路

    由输入端选择运算方式的加、减法运算电路 电路的功能 这是一种配
    发表于 05-08 11:32 1539次阅读
    由输入端选择<b class='flag-5'>运算</b><b class='flag-5'>方式</b>的加、减法<b class='flag-5'>运算</b>电路

    C语言printf()输出格式

    printf 的格式控制的完整格式:% - .n l 或 h 格式字符 下面对组成格式说明的各项加以说明: ①%:表示
    发表于 01-13 16:42 0次下载