【问题标题】:How to do multiply and add three fixed point numbers如何做三个定点数的乘法和加法
【发布时间】:2020-06-26 12:38:00
【问题描述】:

这是问题陈述 -

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 (unsigned short int)。

取uint8_t的最少5位来表示a&b 取unit_16_t的至少11位来表示c

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

a.int = (a >> 3) & 0x3
a.frac = a & 0x7
b.int = (b >> 3) & 0x3
b.frac = b & 0x7

现在我想我通过分离整数和小数部分来使解决方案复杂化。

假设我想将 2.31 与 1.05 相乘。

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

因此您不需要将原始实数的整数部分和小数部分分开。

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

// b - 5位,小数部分最少3位,整数部分高2位

// 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;
}

【问题讨论】:

  • 如果您向我们展示您的尝试,细节可能会更清楚,例如。其中表示在用作乘法函数输入的 8/16/32/64 类型内对齐。事实上,你的问题可能会作为一个不清楚的作业转储被关闭:(
  • 谢谢,添加更多细节 - a & b 是 uint8_t(无符号字符),c 是 uint16_t(无符号短整数)。取 uint8_t 的至少 5 位表示 a & b 取 unit_16_t 的至少 11 位表示 c 使用适当的位掩码提取整数和小数部分,例如 a.int = (a >> 3) & 0x3 a .frac = a & 0x7 b.int = (b >> 3) & 0x3 b.frac = b & 0x7
  • @Ukkadam:将信息放在问题中,而不是在 cmets 中。

标签: c signal-processing fixed-point


【解决方案1】:

乘以定点值与乘以整数完全相同。唯一的复杂之处是您必须跟踪结果中的整数和小数位数。

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

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

两个定点值之和的小数位数与两个加数相同。如果要确保溢出不会破坏总和,则总和的整数位数将等于任一加数中的最大整数位数加一。如果总和不适合您可用的容器,那么您需要将加数右移,丢弃小数位并移动小数点,直到总和适合。

【讨论】:

  • 谢谢!艾略特。有道理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-15
  • 1970-01-01
相关资源
最近更新 更多