相关疑难解决方法(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万
查看次数

bool运算符++和 -

今天在编写一些Visual C++代码时,我遇到了令我惊讶的事情.似乎C++支持bool的++(增量),但不支持 - (减量).这只是一个随机决定,还是有一些原因呢?

这编译:

static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
    hMod = LoadLibrary("xxx");
Run Code Online (Sandbox Code Playgroud)

这不是:

static HMODULE hMod = NULL;
static bool once = true;
if (once--)
    hMod = LoadLibrary("xxx");
Run Code Online (Sandbox Code Playgroud)

c++ boolean increment

101
推荐指数
3
解决办法
1万
查看次数

计算可能溢出的整数运算的最安全,最有效的方法

假设我们有2个常数A&B和一个变量i,所有64位整数.我们想要计算一个简单的通用算术运算,例如:

i * A / B    (1)
Run Code Online (Sandbox Code Playgroud)

为了简化问题,我们假设变量i总是在范围内[INT64_MIN*B/A, INT64_MAX*B/A],因此算术运算(1)的最终结果不会溢出(即:适合该范围[INT64_MIN, INT64_MAX]).

另外,i假设更有可能在友好范围Range1 = [INT64_MIN/A, INT64_MAX/A](即:接近0),但是i可能(不太可能)在该范围之外.在第一种情况下,一个平凡的整数计算i * A不会溢出(这就是我们称之为范围友好的原因); 并且在后一种情况下,i * A将会溢出的平凡整数计算,导致(1)的计算中的错误结果.

什么是"最安全"和"最有效"的计算操作方法(1)(其中"最安全"意味着:保持准确性或至少相当精确,"最有效"意味着:最低平均计算时间),提供i更有可能在友谊范围Range1.

目前,代码中当前实现的解决方案如下:

(int64_t)((double)A / B * i)
Run Code Online (Sandbox Code Playgroud)

哪个解决方案非常安全(没有溢出)虽然不准确(由于双重有效位和53位限制导致的精度损失)并且非常快,因为(double)A / B在编译时预分配了双重除法,只允许在运行时计算双乘法.

c c++

25
推荐指数
2
解决办法
630
查看次数

检测某些整数是否具有特定值的位技巧

是否有任何聪明的位技巧来检测是否有少数整数(比如3或4)具有特定值?

直截了当

bool test(int a, int b, int c, int d)
{
    // The compiler will pretty likely optimize it to (a == d | b == d | c == d)
    return (a == d || b == d || c == d);
}
Run Code Online (Sandbox Code Playgroud)

在GCC汇编到

test(int, int, int, int):
        cmp     ecx, esi
        sete    al
        cmp     ecx, edx
        sete    dl
        or      eax, edx
        cmp     edi, ecx
        sete    dl
        or      eax, edx
        ret
Run Code Online (Sandbox Code Playgroud)

这些sete指令有较高的延迟比我要忍受,所以我宁愿用一些按位(&,|,^ …

c++ optimization performance x86 bit-manipulation

16
推荐指数
1
解决办法
541
查看次数

当我使用 int32_t 循环变量时,为什么我的 for 循环不会停止?

i在我的程序中,我发现当is时循环无法正确退出int32_t。看起来像是整数溢出,并且远大于10,并且循环不会停止。请告诉我发生了什么以及如何在大型项目中避免此错误。

#include <iostream>
#include <stdint.h>
int f(int n){

    for (int32_t i = 0; i < 10; ++i)
    {
        int64_t time = 4500000000 +  (i) * 500000000;
        std::cout << time<< " i: " << i << std::endl;

    }
    return 0;
}

int main ()
{
    return f(10);
}
Run Code Online (Sandbox Code Playgroud)

代码链接

c++

13
推荐指数
1
解决办法
1239
查看次数

在发生溢出的情况下,stdint.h中定义的C99签名整数类型是否表现出良好定义的行为?

对于C(short,int,long等)中的"标准"有符号整数类型的所有操作,如果它们产生超出[TYPE_MIN,TYPE_MAX]间隔的结果(其中TYPE_MIN,TYPE_MAX是最小值和最大整数值),则表现出未定义的行为可以通过特定整数类型存储的.

但是,根据C99标准,所有intN_t类型都需要具有二进制补码表示:

7.8.11.1精确宽度整数类型
1. typedef名称intN_t指定有符号整数类型,其宽度为N,无填充位和二进制补码表示.因此,int8_t表示具有正好8位宽度的有符号整数类型.

这是否意味着intN_tC99 中的类型在整数溢出的情况下表现出良好定义的行为?例如,这段代码定义明确吗?

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(void)
{
    printf("Minimum 32-bit representable number: %" PRId32 "\n", INT32_MAX + 1);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c standards integer-overflow c99

11
推荐指数
1
解决办法
641
查看次数

g ++优化打破了循环

几天前,我遇到了我认为是g ++ 5.3中有关在更高-OX优化级别嵌套for循环的错误.(专门为它-O2而经历过-O3).问题是,如果你有两个嵌套的for循环,它有一些内部和来跟踪总迭代次数,一旦这个总和超过它的最大值,就会阻止外部循环终止.我能够复制的最小代码集是:

int main(){
    int sum = 0;
    //                 Value of 100 million. (2047483648 less than int32 max.)
    int maxInner = 100000000;

    int maxOuter = 30;

    // 100million * 30 = 3 billion. (Larger than int32 max)

    for(int i = 0; i < maxOuter; ++i)
    {
        for(int j = 0; j < maxInner; ++j)
        {
            ++sum;
        }
        std::cout<<"i = "<<i<<" sum = "<<sum<<std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

当使用g++ -o run.me main.cpp它编译时,它按预期输出运行:

i = …
Run Code Online (Sandbox Code Playgroud)

c++ optimization for-loop nested-loops

8
推荐指数
3
解决办法
1049
查看次数

在C/C++中允许有符号整数溢出

希望签名整数在它们变得太大时溢出.如何在不使用下一个最大数据类型的情况下(或者当我已经在int128_t时)实现这一目标?

例如,使用8位整数19*12通常是260,但我希望结果1 11 10 01 00第9位被截止,因此-27.

c c++ integer-overflow

7
推荐指数
2
解决办法
5989
查看次数

(x+1) &gt; 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
查看次数

无符号值之间的减法 - 意外结果

我有两个变量(test1test2),都是无符号的.我需要检查哪一个更大.

我试图了解如果发生溢出会发生什么.

我的第一个测试是使用uint8_t(char)数据类型完成的:

#include <stdio.h>
#include <stdint.h>
#include <math.h>

int main()
{
    uint8_t test1 = 0;
    printf("test1 = %d\n", test1);

    uint8_t test2 = pow(2, 8 * sizeof(test1)) - 1; //max holdable value of uint8_t
    printf("test2 = %d\n", test2);

    uint8_t test3 = test1 - test2;
    printf("test1 - test2 = %d\n", test3);

    if ((test1 - test2) == 0)
        printf("test1 == test2\n");
    if ((test1 - test2) > 0)
        printf("test1 > test2\n");
    if ((test1 - test2) < 0) …
Run Code Online (Sandbox Code Playgroud)

c c++

6
推荐指数
2
解决办法
1425
查看次数