例如,如果一个32位整数溢出,而不是升级int到long,如果我们需要一个仅在2 40之内的范围,我们可以使用一些40位类型,这样我们就可以节省24(64-40)位整数?
如果是这样,怎么样?
我必须处理数十亿和空间是一个更大的约束.
乍一看,这个问题看起来像是如何检测整数溢出的重复?然而,它实际上是显着不同的.
我发现虽然检测无符号整数溢出非常简单,但在C/C++中检测带符号的溢出实际上比大多数人想象的要困难.
最明显但又天真的方式是这样的:
int add(int lhs, int rhs)
{
int sum = lhs + rhs;
if ((lhs >= 0 && sum < rhs) || (lhs < 0 && sum > rhs)) {
/* an overflow has occurred */
abort();
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
这个问题是根据C标准,有符号整数溢出是未定义的行为. 换句话说,根据标准,只要您甚至导致签名溢出,您的程序就像取消引用空指针一样无效.因此,您不能导致未定义的行为,然后尝试在事后检测溢出,如上面的后置条件检查示例.
尽管上面的检查很可能适用于许多编译器,但你不能指望它.实际上,因为C标准说未定义有符号整数溢出,所以一些编译器(如GCC)将在设置优化标志时优化上述检查,因为编译器假定有符号溢出是不可能的.这完全打破了检查溢出的尝试.
因此,检查溢出的另一种可能方法是:
int add(int lhs, int rhs)
{
if (lhs >= 0 && rhs >= 0) {
if (INT_MAX - lhs <= rhs) {
/* overflow …Run Code Online (Sandbox Code Playgroud) 我在SO中徘徊,看到了这个问题.然后我开始想知道我是否可以溢出argc.
标准表示argv[argc]必须是空指针,但如果argc溢出则这将为false.
(我写了一个小的C程序和一个python脚本来测试它,但得到了MemoryError.)
谢谢!
国际标准的基本原理 - 编程语言 - C§5.1.2.2.1 程序启动
规范
argc和argv作为main承认广泛的先前实践的论据.argv[argc]需要是一个空指针,以便在列表末尾提供冗余检查,同样基于通常的做法.
为什么此代码不打印相同的数字?:
long long a, b;
a = 2147483647 + 1;
b = 2147483648;
printf("%lld\n", a);
printf("%lld\n", b);
Run Code Online (Sandbox Code Playgroud)
我知道 int 变量的最大数量是 2147483647,因为 int 变量是 4 字节。但据我所知,long long 变量是 8 字节,但为什么这段代码会这样呢?
众所周知,有符号整数溢出是未定义的行为.但是C++ 11 cstdint文档中有一些有趣的东西:
有符号整数类型,宽度分别为8,16,32和64位,没有填充位,负值使用2的补码(仅当实现直接支持该类型时提供)
这里是我的问题:由于标准明确地说,对int8_t,int16_t,int32_t和int64_t负数是2的补,仍然是这些类型的未定义行为的泛滥?
编辑我检查了C++ 11和C11标准,这是我发现的:
C++ 11,§18.4.1:
标题定义了所有函数,类型和宏,与C标准中的7.20相同.
C11,§7.20.1.1:
typedef名称
intN_t指定有符号整数类型,其宽度为N,无填充位和二进制补码表示.因此,int8_t表示这样的带符号整数类型,其宽度恰好为8位.
我注意到了一些意想不到的行为(意外相对于我的个人期望),我想知道是否有什么东西,如果JVM中有一个错误,或者这可能是一个边缘情况,我不明白究竟是什么细节应该发生.假设我们在main方法中有以下代码:
int i;
int count = 0;
for(i=0; i < Integer.MAX_VALUE; i+=2){
count++;
}
System.out.println(i++);
Run Code Online (Sandbox Code Playgroud)
一个天真的期望是,这将打印Integer.MAX_VALUE-1,最大甚至可表示int.但是,我认为整数算术应该在Java中"翻转",因此Integer.MAX_VALUE应该导致添加1 Integer.MIN_VALUE.由于Integer.MIN_VALUE仍然小于Integer.MAX_VALUE,循环将继续迭代负甚至整数.最终它会回到0,这个过程应该重复为无限循环.
当我实际运行此代码时,我得到非确定性结果.打印的结果往往大约为50万,但确切的值会有所不同.因此,当我认为它应该是一个无限循环时,不仅循环终止,而且它似乎随机终止.这是怎么回事?
我的猜测是,这可能是JVM中的一个错误,或者正在进行大量的时髦优化,这会产生这种预期的行为.这是什么?
我正在实现一个数据库应用程序,我将使用JavaDB和MySQL作为数据库.我的表中有一个ID列,其类型为整数,我使用数据库auto_increment-function作为值.
但是当我获得超过2(或4)亿个帖子和整数时,会发生什么呢?整数溢出并继续或者是我可以处理的异常抛出?
是的,我可以更改为数据类型,但如何检查何时需要?我认为获取last_inserted_id()函数是有问题的,如果我使用long作为ID列的数据类型.
我有一个int x。为简单起见,假设ints 占据范围 -2^31 到 2^31-1。我想计算2*x-1. 我允许x为任何值 0 <= x<= 2^30。如果我计算 2*(2^30),我会得到 2^31,这是整数溢出。
一种解决方案是计算2*(x-1)+1. 比我想要的多了一项减法,但这不应该溢出。但是,编译器会将其优化为2*x-1. 这是源代码的问题吗?这是可执行文件的问题吗?
这是 Godbolt 的输出2*x-1:
func(int): # @func(int)
lea eax, [rdi + rdi]
dec eax
ret
Run Code Online (Sandbox Code Playgroud)
这是 Godbolt 的输出2*(x-1)+1:
func(int): # @func(int)
lea eax, [rdi + rdi]
dec eax
ret
Run Code Online (Sandbox Code Playgroud) c++ integer-overflow compiler-optimization undefined-behavior integer-arithmetic
我经常看到Overflow与vba错误有关的问题.
我的问题是为什么使用integer变量声明而不是仅仅定义所有数值变量(不包括double等)long?
除非您正在执行类似for循环的操作,您可以保证该值不会超过32,767的限制,否则是否会对性能产生影响或其他会导致不使用long?
我一直在研究在数组中查找孤独整数的算法,这里是实现:
int arr[] = {10, 20, 30, 5, 20, 10, 30};
int LonelyInteger = 0;
for(int i=0; i< 7; i++)
{
LonelyInteger = LonelyInteger ^ arr[i];
}
Run Code Online (Sandbox Code Playgroud)
结果是5.
我的问题是 - 据说整数(由XOR操作产生)由于这个操作太大了:
LonelyInteger ^ arr[i]
Run Code Online (Sandbox Code Playgroud)
这导致一个潜在的大整数,int在这种情况下无法用数据类型表示.我的问题是:
XOR生成无法存储在int类型中的如此大的整数值?integer-overflow ×10
c++ ×6
c ×5
bitwise-xor ×1
c++11 ×1
database ×1
integer ×1
java ×1
jvm ×1
lastinsertid ×1
long-integer ×1
signed ×1
vba ×1