【问题标题】:Signed & unsigned integer multiplication有符号和无符号整数乘法
【发布时间】:2013-06-02 17:30:51
【问题描述】:

在定点数学中,我使用大量 16 位信号并使用 32 位中间结果执行乘法运算。例如:

int16_t a = 16384; //-1.0q14  or 1.0*2^14
int16_t b = -24576; // -1.4q14  or 1.4*2^14
int16_t c; // result will be q14

c = (int16_t)(((int32_t)a * (int32_t)b)>>14);

假设 a 是一个 q14 数字,然后 c 与 b 具有相同的缩放比例。

这很好,适用于无符号和有符号算术。

问题是:如果我要混合类型会发生什么?例如,如果我知道乘数“a”的范围总是从 0.0 到 1.0,那么很容易将其设为 unsigned int q15 以获得额外的精度(并将移位计数更改为 15)。但是,我从来不明白如果您尝试在 C 中将有符号和无符号数字相乘并避免它会发生什么。在 ASM 中,我不记得有可以在任何架构上处理混合类型的乘法指令,所以即使 C 做正确的事情,我也不确定它会生成高效的代码。

我是否应该继续在定点代码中不混合有符号和无符号类型的做法?或者这可以很好地工作吗?

【问题讨论】:

  • 这篇文章将回答您有关将有符号和无符号整数相乘时会发生什么的问题。 stackoverflow.com/questions/50605/…。简短的回答是,只要它们的等级(大小)相同,带符号的就会隐式转换为无符号的。
  • 发布答案而不是评论,以便我接受它;-)
  • 当时出于某种原因,我以为我只是回答了你的部分问题,所以我把它作为评论留下了。现在我再看一遍,我不知道为什么我会这么想。谢谢!

标签: c math types multiplication fixed-point


【解决方案1】:

我遇到了类似的问题。它在x64 版本中导致访问冲突崩溃。代码遍历图像扫描线的缓冲区。获取下一条扫描线指针如下:

unsigned char* pImg = ...
int stride = -3324;
unsigned int iRow = 1; // 2, 3, 4, ...
unsigned char* pNextLine = pImg + stride * iRow

负步幅意味着从底部向顶部扫描线迭代。产品stride * iRowsigned * unsigned 被类型转换为unsigned __int64,其值为4294963972,这会将pNextLine 推出程序的内存。

x32 程序版本也是如此,但没有崩溃。可能是因为 x32 pNextLine 指针只是环绕(但保留在程序的内存中)。

【讨论】:

    【解决方案2】:

    This post 讨论有符号和无符号整数相乘时会发生什么。简短的回答是,只要它们的等级(大小)相同,带符号的就会隐式转换为无符号的。

    只要您了解类型转换规则(无论您使用何种编程语言),或使用显式类型转换,并且您还了解从有符号到无符号的类型转换的含义(负数会产生可能看起来像乱码的内容)类型转换为有符号值),那么混合有符号和无符号类型应该没有问题。

    【讨论】:

    • 在我的情况下,根据规则混合类型会导致错误的结果。这就是我所害怕的。
    • 您能否使用您在 a 和 b 中输入的确切值编辑您的帖子,从而得出违反规则的结果?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    相关资源
    最近更新 更多