是否有一般方法来检查给定数据类型(uint32,int等)的溢出或下溢?
我正在做这样的事情:
uint32 a,b,c;
... //initialize a,b,c
if(b < c) {
a -= (c - b)
}
Run Code Online (Sandbox Code Playgroud)
当我在一些迭代后打印时,它会显示一个很大的数字,如:4294963846.
微软已经在GetTickCount的文档中说过,你永远无法比较滴答计数来检查是否已经过了一段时间.例如:
不正确(伪代码):
DWORD endTime = GetTickCount + 10000; //10 s from now
...
if (GetTickCount > endTime)
break;
Run Code Online (Sandbox Code Playgroud)
上面的代码很糟糕,因为它可以对tick计数器进行翻转.例如,假设时钟接近其范围的结尾:
endTime = 0xfffffe00 + 10000
= 0x00002510; //9,488 decimal
Run Code Online (Sandbox Code Playgroud)
然后你执行检查:
if (GetTickCount > endTime)
Run Code Online (Sandbox Code Playgroud)
这是立刻感到满意,因为GetTickCount 是大于endTime:
if (0xfffffe01 > 0x00002510)
Run Code Online (Sandbox Code Playgroud)
相反,你应该总是减去两个时间间隔:
DWORD startTime = GetTickCount;
...
if (GetTickCount - startTime) > 10000 //if it's been 10 seconds
break;
Run Code Online (Sandbox Code Playgroud)
看着同样的数学:
if (GetTickCount - startTime) > 10000
if (0xfffffe01 - 0xfffffe00) > 10000
if (1 > 10000)
Run Code Online (Sandbox Code Playgroud)
在C/C++中,这一点都很好,编译器在某种程度上表现得很好. …
是否可以执行argc = 0的进程?我需要执行一个程序,但它的argc等于0是非常重要的.有没有办法做到这一点?我试图在命令行中放置2 ^ 32个参数,使其看起来好像argc = 0但是参数个数有一个最大限制.
这是一个来自C++引言第五版问题3.26的问题,我不知道它们之间的区别?可能是第二个可以避免溢出.
JavaScript可以处理以下数学:
var result = (20000000 * 48271) % 0x7FFFFFFF;
Run Code Online (Sandbox Code Playgroud)
但是在某些编程语言中,第一次int*int乘法导致的值太大而无法保存在标准的32位整数中.有没有办法在JavaScript中"模拟"这个,并看看如果乘法导致整数溢出,结果计算会是什么?
主要使用python,我已经被宠坏了,不必担心整数溢出.现在我正在使用numpy,我不得不再次担心它.我想在溢出的情况下numpy错误,但它似乎不适用于int64.
import numpy
numpy.seterr(all='raise')
print("{:,}".format(numpy.prod([10]*50)))
# -5,376,172,055,173,529,600
print("{:,}".format(numpy.int64(3200000000) * numpy.int64(3200000000)))
# -8,206,744,073,709,551,616
print("{:,}".format(numpy.int32(320000) * numpy.int32(320000)))
# FloatingPointError: overflow encountered in int_scalars -- Finally getting an error!
Run Code Online (Sandbox Code Playgroud)
我总是可以添加dtype=object修复这些问题,但我认为int64在大多数情况下都是足够好的,它可能会因为难以检测的方式而失败.
为什么seterr只适用于int32?我可以让它适用于int64吗?
我可以找到的numpy.seterr文档的唯一部分可能暗示为什么会出现这种情况的原因如下:
请注意,对整数标量类型(如int16)的操作将像浮点一样处理,并受这些设置的影响.
但是数据类型文档中没有任何内容表明int32和int64在某种程度上在概念上是不同的.不确定int64是否被视为"整数标量类型".
这是一个将int加到另一个的 C 函数,如果发生溢出则失败:
int safe_add(int *value, int delta) {
if (*value >= 0) {
if (delta > INT_MAX - *value) {
return -1;
}
} else {
if (delta < INT_MIN - *value) {
return -1;
}
}
*value += delta;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
safe_add(int*, int):
movl (%rdi), %eax
testl %eax, %eax
js .L2
movl $2147483647, %edx
subl %eax, %edx
cmpl %esi, %edx
jl .L6
.L4:
addl %esi, %eax
movl …Run Code Online (Sandbox Code Playgroud) 我的代码:
#include <stdio.h>
#include <limits.h>
int main()
{
char c = CHAR_MAX;
c += 1;
printf("CHAR_MIN=%d CHAR_MAX=%d c=%d (%c)\n", CHAR_MIN, CHAR_MAX, c, c);
}
Run Code Online (Sandbox Code Playgroud)
输出:
CHAR_MIN=-128 CHAR_MAX=127 c=-128 ()
Run Code Online (Sandbox Code Playgroud)
我们看到,当我们增加一个char设置为的变量时CHAR_MAX,它会环绕到CHAR_MIN。这种行为有保证吗?或者它将是未定义的行为或实现指定的行为?C99 标准对此有何评论?
[注意:将大于 CHAR_MAX (127) 的值赋予 char或C会发生什么-为什么 char c=129 会转换为 -127?没有解决这个问题,因为他们谈论分配一个超出范围的值而不是将一个值增加到一个超出范围的值。]
首先,让我说我理解我所描述的问题是如何以及为什么会发生的.我是计算机科学专业,我理解溢出/下溢和签名/无符号算术.(对于那些不熟悉该主题的人,Apple的安全编码指南会简要讨论整数溢出.)
我的问题是关于在检测到这种错误后报告和恢复,更具体地说是在Objective-C框架的情况下.(我编写和维护CHDataStructures.)我有一些集合类,它们分配用于存储对象的内存并根据需要动态扩展.我还没有看到任何与溢出相关的崩溃,可能是因为我的测试用例主要使用了理智的数据.但是,给定未经验证的值,事情可能会很快爆炸,我想阻止它.
我已经确定了至少两种可能发生这种情况的常见情况:
-initWithCapacity:.简单的部分是检测是否会发生溢出.(例如,在尝试分配length * sizeof(void*)字节之前,我可以检查是否length <= UINT_MAX / sizeof(void*),因为未通过此测试将意味着产品将溢出并可能分配比预期更小的内存区域.在支持它的平台上,checkint.h API是另一种选择.)更难的部分是确定如何优雅地处理它.在第一种情况下,呼叫者可能更好地(或至少在思维模式中)处理故障.第二种情况可能发生在代码中将对象添加到集合中的任何位置,这可能是非常不确定的.
那么,我的问题是:在这种情况下,当整数溢出发生时,"好公民"Objective-C代码如何表现?(理想情况下,由于我的项目是一个与Cocoa中的Foundation基本相同的框架,我想建模它的行为方式以获得最大的"阻抗匹配".我发现的Apple文档中没有提及太多所有这一切.)我认为,无论如何,报告错误是给定的.由于添加对象的API(可能导致方案2)不接受错误参数,我可以做些什么来帮助解决问题,如果有的话?在这种情况下,真正考虑的是什么?如果我能做得更好,我不愿意故意编写容易崩溃的代码......
memory-management error-reporting objective-c integer-overflow
我试图找到 a 的平方int。我的代码如下所示:
long long sqr=0;
int num=77778;
sqr= num*num;
Run Code Online (Sandbox Code Playgroud)
结果应该是6049417284
但是当我检查输出时它显示1754449988。我在做什么错误?
long long应该能够存储结果,但为什么我得到不同的值?
integer-overflow ×10
c ×3
c++ ×3
algorithm ×1
argc ×1
argv ×1
char ×1
clang ×1
delphi ×1
delphi-5 ×1
gcc ×1
javascript ×1
long-long ×1
numpy ×1
objective-c ×1
optimization ×1
overflow ×1
python ×1
standards ×1
underflow ×1