C 如何做三个定点数的乘法和加法

C 如何做三个定点数的乘法和加法,c,signal-processing,fixed-point,C,Signal Processing,Fixed Point,这是问题陈述- a:5位表示,其中2个MSB位为整数部分,3个LSB位为小数部分 b:5位表示,其中2个MSB位为整数部分,3个LSB位为小数部分 c:11位表示,其中MSB位为整数部分,10位LSB位为小数部分 我正在尝试编写C代码来执行: d=a*b+c 如何优化这一点,使用什么样的数据结构等 谢谢,添加更多细节- a&b为uint8_t(无符号字符), c是uint16_t(无符号短整数) 取uint8的至少5位表示a和b 取单位_16_t的至少11位表示c 使用适当的位掩码提取整数和小数

这是问题陈述-

a:5位表示,其中2个MSB位为整数部分,3个LSB位为小数部分 b:5位表示,其中2个MSB位为整数部分,3个LSB位为小数部分 c:11位表示,其中MSB位为整数部分,10位LSB位为小数部分

我正在尝试编写C代码来执行:

d=a*b+c

如何优化这一点,使用什么样的数据结构等


谢谢,添加更多细节- a&b为uint8_t(无符号字符), c是uint16_t(无符号短整数)

取uint8的至少5位表示a和b 取单位_16_t的至少11位表示c

使用适当的位掩码提取整数和小数部分 比如

现在我想我把整数部分和小数部分分开,使解决方案过于复杂了

假设我想用1.05乘以2.31

我们可以将231乘以105,然后再除以10000

所以你不需要分离原始实数的整数和小数部分

按照这些思路,什么是好的解决方案? //a-5位,至少3位为小数部分,上2位为整数部分

#define uint8_t (unsigned char)

#define uint16_t (unsigned short int)

uint16_t   compute(uint8_t a, uint8_t b, uint16_t c)
{
     uint16_t multval = a * b;  // the least 6 bits represent the fractional part, the upper 4 bits represent integer part
     uint8_t ab_int = multval >> 6; // integer part of a*b
     uint8_t ab_frac = multval & 0x3F; // fractional part of a*b
     uint16_t ab_adjusted = (ab_int << 10) | ab_frac;
     uint16 sum = c + ab_adjusted;
     return sum;
}
//b-5位,至少3位为小数部分,上2位为整数部分

#define uint8_t (unsigned char)

#define uint16_t (unsigned short int)

uint16_t   compute(uint8_t a, uint8_t b, uint16_t c)
{
     uint16_t multval = a * b;  // the least 6 bits represent the fractional part, the upper 4 bits represent integer part
     uint8_t ab_int = multval >> 6; // integer part of a*b
     uint8_t ab_frac = multval & 0x3F; // fractional part of a*b
     uint16_t ab_adjusted = (ab_int << 10) | ab_frac;
     uint16 sum = c + ab_adjusted;
     return sum;
}
//c-11位,至少10位为小数部分,MSB为整数部分

#define uint8_t (unsigned char)

#define uint16_t (unsigned short int)

uint16_t   compute(uint8_t a, uint8_t b, uint16_t c)
{
     uint16_t multval = a * b;  // the least 6 bits represent the fractional part, the upper 4 bits represent integer part
     uint8_t ab_int = multval >> 6; // integer part of a*b
     uint8_t ab_frac = multval & 0x3F; // fractional part of a*b
     uint16_t ab_adjusted = (ab_int << 10) | ab_frac;
     uint16 sum = c + ab_adjusted;
     return sum;
}
#定义uint8_t(无符号字符)
#定义uint16_t(无符号短整型)
uint16_t计算(uint8_t a、uint8_t b、uint16_t c)
{
uint16_t multval=a*b;//至少6位表示小数部分,上面4位表示整数部分
uint8\u t ab\u int=multval>>6;//a*b的整数部分
uint8\u t ab\u frac=multval&0x3F;//a*b的小数部分

uint16_t ab_adjusted=(ab_int乘以定点值与乘以整数完全相同。唯一的复杂之处是必须跟踪结果中整数和分数位数

如果有两个无符号8位值,其中两个值的底部F_1和F_2位为分数位,则16位乘积将有F_1+F_2分数位。同样,乘积将有I_1+I_2整数位。如果在8位容器中对被乘数进行右对齐,则乘积在其16位中也将右对齐-位容器

加法更为复杂。在进行整数加法之前,必须对齐加法器的基点,这意味着它们需要具有相同数量的分数位(再次假设它们是右对齐的)。可以通过将具有更多分数位的操作数向右移动来完成此操作(这会牺牲精度和分辨率)或者将分数位数较少的值向右移动(这意味着总和需要更多的总位数)。选择权在您


两个定点值之和的分数位数与两个加数的分数位数相同。如果要确保溢出不会损坏该和,则该和将具有一个整数位数,该整数位数等于任一加数中的最大整数位数,再加上一个。如果该和无法放入可用的容器中,然后你需要将加数右移,丢弃分数位并移动基数点,直到和合适为止。

如果你向我们展示你的尝试,细节可能会更清楚,例如,在用作乘法函数输入的8/16/32/64类型中,表示形式是对齐的。事实上,你的问题很可能会以简单的方式结束ar作业转储:(谢谢,添加了更多细节-a和b是uint8_t(无符号字符),c是uint16_t(无符号短整型)。取uint8_t的至少5位表示a和b,取单位16_t的至少11位表示c,使用适当的位掩码提取整数和小数部分,如a.int=(a>>3)&0x3 a.frac=a&0x7 b.int=(b>>3)&0x3 b.frac=b&0x7@Ukkadam:将信息放在问题中,而不是评论中。谢谢!埃利奥特。有道理。