繁体   English   中英

有符号和无符号整数乘法

[英]Signed & unsigned integer multiplication

在定点数学中,我使用许多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的范围内,则很想将其设置为无符号int q15以获得额外的精度(并将移位计数更改为15)。 但是,如果您尝试在C中将带符号数和无符号数相乘并避免使用它,我永远不会理解会发生什么。 在ASM中,我不记得有一个乘法指令可以在任何体系结构上使用混合类型,因此即使C做了正确的事情,我也不确定它会生成有效的代码。

我应该继续我的做法,即不将定点代码中的带符号的无符号类型混合在一起吗? 还是可以很好地工作?

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

只要您了解类型转换规则(使用您所编程的任何语言),或使用显式类型转换,并且您还理解类型转换从有符号到无符号的含义(当数字类型转换为无符号时,负数会产生乱码)签名值),那么将签名和未签名类型混合使用就不会有问题。

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

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

负步幅表示从底部扫描线到顶部扫描线。 产品4294963972 stride * iRow即有signed * unsigned被强制转换为unsigned __int64 ,其值4294963972pNextLine推出程序的内存。

x32程序版本也会发生相同的情况,但是不会崩溃。 可能是因为x32 pNextLine指针只是回绕(但停留在程序的内存中)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM