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

减去/添加值而不会出现溢出或下溢

想象一下,我有两个无符号字节bx.我需要计算bsubas b - xbaddas b + x.但是,我不希望在这些操作期间发生下溢/溢出.例如(伪代码):

b = 3; x = 5;
bsub = b - x; // bsub must be 0, not 254
Run Code Online (Sandbox Code Playgroud)

b = 250; x = 10;
badd = b + x; // badd must be 255, not 4
Run Code Online (Sandbox Code Playgroud)

显而易见的方法包括分支:

bsub = b - min(b, x);
badd = b + min(255 - b, x);
Run Code Online (Sandbox Code Playgroud)

我只是想知道是否有更好的方法来做到这一点,即通过一些hacky位操作?

c c++ optimization bit-manipulation saturation-arithmetic

82
推荐指数
4
解决办法
1万
查看次数

如何在C中检测整数溢出

我们知道CPython在数字变大时会无声地将整数提升为长整数(允许任意精度算术)。

我们如何检测的溢出intlong long纯C?

c overflow

20
推荐指数
3
解决办法
3774
查看次数

如何在固定宽度类型上强制无符号算术?

以下(C99和更新)代码想要计算一个方块,限制为与原始固定宽度类型相同的位数.

    #include <stdint.h>
     uint8_t  sqr8( uint8_t x) { return x*x; }
    uint16_t sqr16(uint16_t x) { return x*x; }
    uint32_t sqr32(uint32_t x) { return x*x; }
    uint64_t sqr64(uint64_t x) { return x*x; }
Run Code Online (Sandbox Code Playgroud)

问题是:取决于int大小,可以对提升为(signed)int的参数执行一些乘法,结果溢出(signed)int,因此就标准而言是未定义的结果; 并且可以想象错误的结果,特别是在(越来越罕见的)不使用二进制补码的机器.

如果int是32位(分别为16位,64位,80位或128位),即发生对于sqr16(相应的sqr8,sqr32,sqr64)时x0xFFFFF(相应的0xFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF).4个功能都不能在C99下正式移植!!

C11或更高版本,或某些版本的C++,是否解决了这种不幸的情况?


一个简单,有效的解决方案是:

    #include <stdint.h>
     uint8_t  sqr8( uint8_t x) { return 1u*x*x; }
    uint16_t sqr16(uint16_t x) { return 1u*x*x; }
    uint32_t sqr32(uint32_t …
Run Code Online (Sandbox Code Playgroud)

c c++ standards-compliance c99

14
推荐指数
1
解决办法
919
查看次数

x86汇编:INC和DEC指令和溢出标志

在x86汇编中,当有符号整数上的addsub操作溢出时,溢出标志置位,当无符号整数上的操作溢出时,置载标志置位.

然而,当谈到incdec说明,情况似乎有些不同.根据该网站,该inc指令根本不影响进位标志.

但我不能找到有关如何的任何信息incdec如果有的话,会影响溢出标志.

发生整数溢出时执行incdec设置溢出标志?对于有符号整数和无符号整数,这种行为是否相同?

============================= 编辑 ==================== =========

好的,基本上这里的共识是,就设置标志而言,INC和DEC应该与ADD和SUB的行为相同,但进位标志除外.这也是英特尔手册中的内容.

问题是,当涉及到无符号整数时,我实际上无法在实践中重现这种行为.

请考虑以下汇编代码(使用GCC内联汇编以便更轻松地打印结果.)

int8_t ovf = 0;

__asm__
(
    "movb $-128, %%bh;"
    "decb %%bh;"
    "seto %b0;"
    : "=g"(ovf)
    :
    : "%bh"
);

printf("Overflow flag: %d\n", ovf);
Run Code Online (Sandbox Code Playgroud)

这里我们递减一个带符号的8位值-128.由于-128是可能的最小值,溢出是不可避免的.正如所料,这打印出:Overflow flag: 1

但是当我们使用无符号值执行相同操作时,行为并不像我预期的那样:

int8_t ovf = 0;

__asm__
(
    "movb $255, %%bh;"
    "incb %%bh;"
    "seto %b0;"
    : "=g"(ovf)
    :
    : "%bh"
); …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly x86-64 inline-assembly

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

检测整数溢出

如何检测D中的整数溢出?(检查携带标志?)

原始示例:

ubyte a = 100;
ubyte b = 200;
ubyte c = a + b;
// c can't represent 300; how to detect the overflow now?
Run Code Online (Sandbox Code Playgroud)

修改后的例子:

uint a = 2_000_000_000;
uint b = 3_000_000_000;
uint c = a + b;
// c can't represent 5_000_000_000; how to detect the overflow now?
Run Code Online (Sandbox Code Playgroud)

还有乘法和前/后增量.

int d

8
推荐指数
2
解决办法
1259
查看次数

从C程序读取标志寄存器

为了好奇,我试图读取标志寄存器并以一种很好的方式将其打印出来.

我已经尝试使用gcc的asm关键字阅读它,但我无法让它工作.任何提示如何做到这一点?我正在运行Intel Core 2 Duo和Mac OS X.以下代码就是我所拥有的.我希望能告诉我是否发生溢出:

#include <stdio.h>

int main (void){
  int a=10, b=0, bold=0;
  printf("%d\n",b);
  while(1){
    a++;
  __asm__ ("pushf\n\t"
   "movl 4(%%esp), %%eax\n\t"
   "movl %%eax , %0\n\t"
   :"=r"(b)      
   :         
   :"%eax"        
   ); 
  if(b!=bold){ 
    printf("register changed \n %d\t to\t %d",bold , b);
  }
  bold = b;
  }
}
Run Code Online (Sandbox Code Playgroud)

这给出了分段错误.当我运行gdb时,我得到了这个:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x000000005fbfee5c
0x0000000100000eaf in main () at asm.c:9
9       asm ("pushf \n\t"
Run Code Online (Sandbox Code Playgroud)

c x86 assembly flags

6
推荐指数
3
解决办法
6350
查看次数

MSVC 是否有溢出检查数学函数?

在寻找对有符号和无符号整数算术进行溢出检查的函数时,我遇到了这个答案,它提供了很好的编译器内在函数,可以在 GCC 中进行检查数学。由于我当前编写的代码需要跨平台,因此我也需要 MSVC(Microsoft Visual Studio)编译器类似的东西。

是否存在或者我必须手动实现它?

c++ integer-overflow visual-c++

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

优化正在扼杀我在clang 6中的整数溢出检查

我有一些针对某些财务应用程序的定点实现.它基本上是一个包含在类中的整数,它基于给定N的十进制数作为小数.该类是偏执的并检查溢出,但是当我在发布模式下运行我的测试时,它们都失败了,最后我创建了这个演示问题的最小例子:

#include <iostream>
#include <sstream>

template <typename T, typename U>
typename std::enable_if<std::is_convertible<U, std::string>::value, T>::type 
FromString(U&& str)
{
    std::stringstream ss;
    ss << str;
    T ret;
    ss >> ret;
    return ret;
}

int main()
{
    int NewAccu=32;
    int N=10;

    using T = int64_t;

    T l = 10;
    T r = FromString<T>("1" + std::string(NewAccu - N, '0'));
    if (l == 0 || r == 0) {
        return 0;
    }
    T res = l * r;
    std::cout << l << std::endl;
    std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ optimization fixed-point integer-overflow c++11

4
推荐指数
1
解决办法
498
查看次数

64位无符号整数可以有多大?

我很清楚64位有符号整数可以有多大? 多亏了这个问题及其简单明了的答案。

因此,据此,我可以说an unsigned int可以是2 ^ 64-1,而不是2 ^ 63-1吗?

2^63 - 1:    0111111111111111111111111111111111111111111111111111111111111111

2^64 - 1:    1111111111111111111111111111111111111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)

当且仅当我正确地获得它时,如何才能检测到未签名的溢出?以二进制补码表示的带符号整数的溢出将侵入最高位位置,并返回负数。但是这种未签名的情况如何?

c

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