c - 按位检查有符号乘法溢出会产生意外结果

标签 c bit-manipulation overflow

我在编写一个函数来验证两个有符号整数的乘法是否会超出使用按位运算的整数范围时遇到困难。

其中一项测试通过了两个整数:-40 和 7。结果是 -280。该测试应该通过,因为 -280 完全在可接受的整数范围内,但我的函数告诉我它失败了。我注意到,每次传递两个产生负乘积的整数时,我都会得到相同的错误结果。代码和测试如下。感谢您的帮助!

我尝试打印出每一步的二进制字符串,以找出为什么结束右移会产生 1。 对于此程序,条件必须采用以下形式:hiproduct = (loproduct >> 31)。

/* 
Function: Take two integers and determine if their product would produce an overflow within Integer boundaries using bit manipulation.
*/

bool tmult_ok(int x, int y) {
    long lx = (long)x;
    long ly = (long)y;
    long hiproduct = lx * ly; // These two are intentionally the same
    long loproduct = lx * ly; // and become different once masks apply
    printf("products: %d\n", hiproduct);

    long himask = 0xFFFFFFFF00000000;
    long lomask = 0x00000000FFFFFFFF;
    hiproduct = hiproduct & himask;
    loproduct = loproduct & lomask;

    printf("TMult result: %d, %d\n", hiproduct, loproduct);
    printf("Shifted loproduct: %d\n", (loproduct >> 31));
    return (hiproduct == (loproduct >> 31));
}

// Excerpt from main() in the test.c file -- not actual location!
int int1 = -40;
int int2 = 7;
assert(tmult_ok(int1, int2)); // True if no overflow would occur
printf("TMult Success Complete\n");

运行时,我收到以下输出:

products: -280
TMult result: 0, -280
Shifted loproduct: 1
Assertion failed: (tmult_ok(int3, int4)), function main, file test.c, line 24.
Abort trap: 6

预期的结果是return语句中的条件为true,因此返回true。

最佳答案

-280 的值为 0xfffffee8。如果右移31,由于符号扩展,最终结果将是0xffffffff(-1)

关于c - 按位检查有符号乘法溢出会产生意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58046087/

相关文章:

c++ - 可以从进程核心访问释放的内存段吗?

java - 传递字节数组出现越界错误,但它通过了 junit 测试

C++ - 创建位和半字节的整数

javascript - 完全禁用 DIV 中任何类型的垂直滚动

c - 将常量指针作为参数传递给另一个函数的问题

c - 如何在文件描述符上创建选择 block

c - 它打印什么以及如何将其转换为指针算术?

java - 删除字节的最后一位

c - C语言中如何避免缓冲区溢出

html - 我想让overflow-x隐藏并且overflow-y可见