6

在定点数学中,我使用了很多 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 做了正确的事情,我也不确定它是否会生成高效的代码。

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

4

2 回答 2

6

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

只要您了解类型转换规则(您正在编程的任何语言),或使用显式类型转换,并且您还了解从有符号到无符号的类型转换的含义(负数将产生在类型转换为有符号值),那么混合有符号和无符号类型应该没有问题。

于 2013-06-11T00:24:23.123 回答
0

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

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

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

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

于 2019-04-05T08:33:49.787 回答