相关疑难解决方法(0)

如何检测无符号整数乘法溢出?

我在C++编写一个程序来找到所有的解决方案b = c ^,其中一个,bc ^一起使用所有的数字0-9只出现一次.该方案在循环值b,并且在每次跑了数字计数程序,b一个b以检查是否数字的条件感到满意.

然而,当可以产生伪解一个b溢出整数限制.我最终使用以下代码检查:

unsigned long b, c, c_test;
...
c_test=c*b;         // Possible overflow
if (c_test/b != c) {/* There has been an overflow*/}
else c=c_test;      // No overflow
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来测试溢出?我知道有些芯片有一个内部标志,当溢出发生时会设置,但我从未见过通过C或C++访问它.


请注意,在C和C++中,签名 int溢出是未定义的行为,因此您必须在不实际导致它的情况下检测它.有关添加前的signed int overflow,请参阅在C/C++中检测带符号的溢出

c c++ integer-overflow

593
推荐指数
19
解决办法
30万
查看次数

(x+1) > x 如何评估为 0 和 1?

我正在学习未定义的行为,并在没有任何明确解释的情况下偶然发现了这段代码:

#include <stdio.h>
#include <limits.h>

int foo ( int x) {
    printf ("% d\n" ,  x );   //2147483647
    printf ("% d\n" ,  x+1 ); //-2147483648  overflow
    return ( x+1 ) > x ;      // 1 but How????
}

int main ( void ) {
    printf ("% d\n" ,  INT_MAX );     //2147483647
    printf ("% d\n" ,  INT_MAX+1 );   //-2147483648  overflow
    printf ("% d\n" , ( INT_MAX+1 ) > INT_MAX );  //0  makes sense, since -ve < +ve
    printf ("% d\n" , …
Run Code Online (Sandbox Code Playgroud)

c c++ undefined-behavior

7
推荐指数
1
解决办法
265
查看次数

绕过CBMC检测到的无符号加法溢出

CBMC在以下行中检测到可能的无符号加法溢出:

l = (t + *b)&(0xffffffffL);
c += (l < t);
Run Code Online (Sandbox Code Playgroud)

我同意第一行有可能出现溢出,但我正在处理CBMC无法查看的下一行的进位.如果有溢出,我设置进位1.所以,因为我知道这个,这就是我希望我的代码工作的方式,我想继续进行验证过程.那么,我怎么告诉CBMC忽略这个错误并继续前进呢?

c integer model-checking integer-overflow cbmc

5
推荐指数
1
解决办法
246
查看次数

C中的按位运算比较两个整数

我最近在我的一个课程中接受了测验.问题如下:

cmp在C中编写一个函数(调用),它接受两个整数(xy)并返回:-1if x< y,0if x= y,1if x> y.写得cmp尽可能简洁.

我能想到的最简洁的功能是:

int cmp(int x, int y) {
    return ((x < y) ? (-1) : ((x == y) ? (0) : (1)));
}
Run Code Online (Sandbox Code Playgroud)

但我有一种感觉,我可以用一些操作来更简洁地做到这一点.也许是&^?的结合?这已经困扰了我过去的几天,我想知道是否有其实IS更好的方式来做到这一点?

c bit-manipulation bitwise-operators

5
推荐指数
2
解决办法
3041
查看次数

如何在不损失结果范围的情况下将C中的uint转换为int

我想要两个无界整数之间的差异,每个整数都由一个uint32_t值表示,该值是取2 ^ 32为模的无界整数。如,例如,TCP序列号。请注意,模数2 ^ 32表示形式可以环绕0,这与更严格的问题不允许环绕0有关

假定基础无界整数之间的差在正常范围内int。我想要这个带符号的差异值。换句话说,返回一个正常int范围内的值,该值等于两个uint32_t输入模2 ^ 32之差。

例如,0 - 0xffffffff = 1因为我们假设基础无界整数在int范围内。证明:如果A mod 2 ^ 32 = 0且B mod 2 ^ 32 = 0xffffffff,则(A = 0,B = -1)(mod 2 ^ 32)因此(AB = 1)(mod 2 ^ 32)和在int此模级的范围内,具有单个代表1

我使用了以下代码:

static inline int sub_tcp_sn(uint32_t a, uint32_t b)
{
    uint32_t delta = a - b;

    // this would work on most systems
    return delta;

    // …
Run Code Online (Sandbox Code Playgroud)

c math language-lawyer

5
推荐指数
1
解决办法
131
查看次数

为什么/如何在此签名溢出测试中编译未定义的行为,以便它可以在x86上工作但不能在ARM64上工作?

当我在断言测试运行期间遇到一个奇怪的问题时,我正在自学CSAPP并得到一个奇怪的结果.

我不知道该怎么开始这个问题,所以让我先得到代码(文件名在评论中可见):

// File: 2.30.c
// Author: iBug

int tadd_ok(int x, int y) {
    if ((x ^ y) >> 31)
        return 1;  // A positive number and a negative integer always add without problem
    if (x < 0)
        return (x + y) < y;
    if (x > 0)
        return (x + y) > y;
    // x == 0
    return 1;
}
Run Code Online (Sandbox Code Playgroud)
// File: 2.30-test.c
// Author: iBug

#include <assert.h>

int tadd_ok(int x, int y);

int main() {
    assert(sizeof(int) == 4); …
Run Code Online (Sandbox Code Playgroud)

c gcc integer-overflow undefined-behavior arm64

3
推荐指数
2
解决办法
353
查看次数