定点数加减运算
文章目录
- 定点数加减运算
- 格式相同
- 位宽相同但不同格式运算
- 位宽不同的定点数运算
- 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 的加法,需要进行小数点对齐。
- 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语言的移位运算自带的。
- 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位,同时去掉多余的小数位数