【问题标题】:Multiplication of 32 bits numbers in CC中32位数字的乘法
【发布时间】:2015-03-05 19:49:57
【问题描述】:

为什么下面的代码会产生这个错误?

error: left shift count >= width of type [-Werror]

代码:

int32_t a,b;
int64_t apo;
a = 2673;
b = 19;
apo = BIG_MULL(a,b);
printf("\n %ld \n", apo );

找到的宏here:

#define WORD_MASK ((1<<16) - 1)
#define LOW_WORD(x)  (x & WORD_MASK)
#define HIGH_WORD(x) ((x & (WORD_MASK<<16)) >> 16)
#define BIG_MULL(a, b) \
((LOW_WORD(a)  * LOW_WORD(b))  <<  0) + \
((LOW_WORD(a)  * HIGH_WORD(b)) << 16) + \
((HIGH_WORD(a) * LOW_WORD(b))  << 16) + \
((HIGH_WORD(a) * HIGH_WORD(b)) << 32)

我正在尝试乘以 32 位的有符号值。目标机器不支持 64 位数学。

【问题讨论】:

  • (HIGH_WORD(a) * HIGH_WORD(b)) &lt;&lt; 32ab的类型是什么?
  • @HuStmpHrrr 让它成为答案

标签: c 64-bit 32-bit multiplication fixed-point


【解决方案1】:

假设您尝试在宏中手动将两个 32 位 int 倍增为 64 位结果,

((HIGH_WORD(a) * HIGH_WORD(b)) << 32

移动超出了 int 的长度,所以你有这个错误。

如果你想让它工作,先把BIG_MULL改成一个函数,然后:

  1. 转换为long long 并执行乘法运算。 long long 在 32 位 int 的系统中通常足够长。
  2. 继续使用适当的结构进行模拟。

第二个有点微妙,但可行。首先你需要对unsigned int进行操作并拥有

struct {
    unsigned int low, high;
} bigmul_result;

并执行您在宏中所做的事情,但转身

((LOW_WORD(a)  * HIGH_WORD(b)) << 16) + \
((HIGH_WORD(a) * LOW_WORD(b))  << 16)

(((LOW_WORD(a)  * HIGH_WORD(b)) + (HIGH_WORD(a) * LOW_WORD(b))) << 16)

这样很容易记住检查总和以查看是否设置了第 17 位。如果是这样,请将 1 添加到 high

【讨论】:

  • 我给了你一票,但我还是要评论,如果系统有一个 64 位的unsigned long long,那么宏完全没用,因为你可以简单地这样做ull_t result = (ull_t)a * (ull_t)b where @ 987654334@ 是unsigned long long 的类型定义。这些宏是为没有内置支持 64 位数学的微型嵌入式系统设计的。
  • 是的,这可能是原因:)
  • @user3386109 注意:我正在使用其中一个“微型嵌入式系统”,(1&lt;&lt;16) 是 UB,int 是 16 位的,更不用说 ((LOW_WORD(a) * HIGH_WORD(b)) &lt;&lt; 16) 的问题了。 IAC,我的代码确实有 64 位类型。 IOW,宏有很多问题。
  • @chux 我很想添加一个答案,说明如何在具有 32 位 long ints 且不支持 64 位类型的系统上正确进行乘法运算,但尚不清楚我是 OP 实际上想要完成的。这个答案解决了直接的问题,“该错误消息是什么意思?”
  • @chux 正是我的情况。下次跟着你的直觉走! :) 那将是我不支持 64 位数学的性能。 @user3386109 我不支持 64 位数学。所以实际上我产生的结果我必须将它保存在两个变量中?一个 32 位用于整数部分,另一个用于小数部分?所以实际上apo 变量int64_t 必须变成两个......?或者这是一个编译器工作,这意味着即使我声明一个 64 位变量,机器也会将它保存在两个 32 位寄存器中?我有没有提到感谢您抽出宝贵的时间? :P ...很多!
猜你喜欢
  • 1970-01-01
  • 2023-03-03
  • 2014-01-09
  • 2019-08-24
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多