> 文章列表 > 定点数加减运算

定点数加减运算

定点数加减运算

定点数加减运算

定点数加减运算

文章目录

  • 定点数加减运算
    • 格式相同
    • 位宽相同但不同格式运算
    • 位宽不同的定点数运算
      • 1.转换为S5.10格式的相同位宽
      • 2.统一转换为S10.5格式的相同位宽

定点数运算可直接通过处理器内置的整数单元实现

格式相同

加减法就是对应二进制形式的有符号整数的加减运算

例如 2.71875的S10.5定点数 与 3.15625的S10.5定点数的减法如下图所示

定点数加减运算

对应计算过程如下:

signed short a=0x0057;     // 2.71875 (S10.5)
signed short b=0x0065;     // 3.15625 (S10.5)
signed short result=a-b;   // -0.4375 (S10.5)

位宽相同但不同格式运算

需要考虑2个问题:

  • 运算输出的定点数格式
  • 小数点如何对齐

无非2种方法,一种是A向B对齐,一种是B向A对齐

例如 S10.5格式的定点数A 2.71875 和 S5.10 格式的定点数B -3.15625 的加法,需要进行小数点对齐。

  1. B向A对齐,即 S5.10对齐到S10.5

通常手法,对小数点位数多的定点数对应的二进制进行右移。

将S5.10 格式的定点数B -3.15625 所对应的有符号整数带符号扩展右移5位,实现小数对齐

注意对于整数,右移时高位扩展的位填充0,对于负数填充1

定点数加减运算

代码运算为:

signed short a= 87;
signed short b=-3232;
// b >> 5 整体右移,去掉多余小数部分,同时整数部分根据符号位填充
signed short result=a+(b>>5); double result_float=(double)result/(double)(1<<5); // 最终保留5位小数

这里:高位符号扩展是C语言的移位运算自带的。

  1. A向B对齐,即 S10.5对齐到S5.10

小数点位数少的定点数进行左移实现小数点对齐,但左移可能导致数据溢出,只有确保不溢出的情况下才这样操作。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DcKYxyO3-1681620368783)(https://files.mdnice.com/user/27157/388db961-6d8f-4f80-b15a-1388d5eb6432.png)]

对应代码为:

signed short a= 87;
signed short b=-3232;
signed short result=(a<<5)+b;double result_float=(double)result/(double)(1<<10);

位宽不同的定点数运算

核心是小数点对齐。通过位宽扩展使得两个数据格式相同,并且小数点对齐

1.转换为S5.10格式的相同位宽

例如 S2.5格式的定点数2.71875 和 S5.10格式的定点数 -3.15625相加

可以统一转换为S5.10格式的相同位宽定点数进行运算
定点数加减运算

代码为:

signed char  a= 87;
signed short b=-3232;
signed short result=(((unsigned short) a)<<5)+b;double result_float=(double)result/(double)(1<<10);

这里a的定义是 signed char,对应格式为S2.5的8位定点数。(unsigned short) a是扩展为16位位宽,再和b相加

2.统一转换为S10.5格式的相同位宽

考虑到S2.5小数位数为5位,而S5.10总共16位位宽,可以统一转换为16位位宽且小数部分为5的定点数,其格式为S10.5
定点数加减运算

代码为:

signed char  a= 87;
signed short b=-3232;
signed short result=(unsigned short)a+(b>>5);double result_float=(double)result/(double)(1<<5);

(unsigned short)a将a转换为16位位宽数据,b>>5将b右移扩展5位,同时去掉多余的小数位数