我已经读了很多地方,整数溢出是定义在C中不同于签名的对手。 下stream是否一样? 例如: unsigned int x = -1; // Does x == UINT_MAX? 谢谢。 我不记得在哪里,但我读的地方,无符号整数types的算术是模块化的,所以如果是这样的话-1 -1 UINT_MAX mod(UINT_MAX + 1)。
我正在为MATLAB / Octave中的一些VHDL代码validation工具。 因此我需要产生“真正”溢出的数据types: intmax('int32') + 1 ans = -2147483648 稍后,如果我可以定义一个variables的位宽,这将是有帮助的,但是现在并不那么重要。 当我build立一个类似C的例子,variables增加到小于零时,它会永远旋转: test = int32(2^30); while (test > 0) test = test + int32(1); end 我尝试的另一种方法是一个自定义的“溢出” – 程序,每次在数字被改变后被调用。 这种做法非常缓慢,不切实际,根本不适用于所有情况。 有什么build议么?
在几种现代编程语言(包括C ++,Java和C#)中,该语言允许在运行时发生整数溢出 ,而不会引起任何types的错误情况。 例如,考虑这个(人为的)C#方法,它不考虑上溢/下溢的可能性。 (为了简洁,该方法也不处理指定列表为空引用的情况。) //Returns the sum of the values in the specified list. private static int sumList(List<int> list) { int sum = 0; foreach (int listItem in list) { sum += listItem; } return sum; } 如果这个方法被调用如下: List<int> list = new List<int>(); list.Add(2000000000); list.Add(2000000000); int sum = sumList(list); sumList()方法中会发生溢出(因为C#中的inttypes是一个32位有符号整数,并且列表中的值的总和超过了最大32位有符号整数的值)。 sumvariables的值是-294967296(不是4000000000的值)。 这最有可能不是sumList方法的(假设的)开发者所期望的。 显然,开发人员可以使用各种技术来避免整数溢出的可能性,例如在Java中使用BigIntegertypes或C#中的checked关键字和/checked编译器开关。 然而,我感兴趣的问题是为什么这些语言默认情况下允许整数溢出发生,而不是在例如运行时执行操作时引发exception溢出。 […]
我们有一些整数算术,由于历史的原因,在PHP上的工作方式与在一些静态types的语言中一样。 自从我们上次升级PHP以来,溢出整数的行为已经改变。 基本上我们使用下面的公式: function f($x1, $x2, $x3, $x4) { return (($x1 + $x2) ^ $x3) + $x4; } 但是,即使转换: function f($x1, $x2, $x3, $x4) { return intval(intval(intval($x1 + $x2) ^ $x3) + $x4); } 我仍然结束了完全错误的数字… 例如,在$ x1 = -1580033017,$ x2 = -2072974554,$ x3 = -1170476976)和$ x4 = -1007518822的情况下,我最终得到了PHP中的-30512150和C#中的1617621783。 只要加在一起$ x1和$ x2我不能得到正确的答案: 在C#中我得到 (-1580033017 + -2072974554) […]
乍一看,这个问题可能看起来像是如何检测整数溢出重复? 但是它实际上是显着不同的。 我发现虽然检测到一个无符号的整数溢出非常微不足道,但是在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; } 这个问题是根据C标准,有符号整数溢出是未定义的行为。 换句话说,根据这个标准,只要你甚至导致了一个签名溢出,你的程序就像你解引用一个空指针一样无效。 所以你不能导致未定义的行为,然后尝试检测事实后的溢出,就像在上面的post-condition检查的例子中一样。 即使上面的检查可能在许多编译器上工作,你也不能指望它。 事实上,因为C标准说未定义有符号整数溢出,所以有些编译器(比如GCC)会在优化标志被设置的时候优化掉上面的检查 ,因为编译器假定一个签名溢出是不可能的。 这完全打破了检查溢出的企图。 所以,另一种检查溢出的方法是: […]
正如我们所知,有符号整数溢出是未定义的行为 。 但在C ++ 11 cstdint文档中有一些有趣的cstdint : 有符号整数types,其宽度分别为8,16,32和64位,没有填充位, 2的补码用于负值 (只有在实现直接支持该types时才提供) 请参阅链接 这里是我的问题:因为标准明确指出,对于int8_t , int16_t , int32_t和int64_t负数是2的补码,仍然是这些types的溢出未定义的行为? 编辑我检查了C ++ 11和C11标准,这里是我发现: C ++ 11,§18.4.1: 标题定义了与C标准中的7.20相同的所有函数,types和macros。 C11,§7.20.1.1: typedef名称intN_t指定宽度为N,无填充位和二进制补码表示的有符号整数types。 因此, int8_t表示宽度恰好为8位的带符号整数types。
无符号整数溢出由C和C ++标准定义。 例如, C99标准 (第§6.2.5/9 )说 涉及无符号操作数的计算永远不会溢出,因为无法用结果无符号整数types表示的结果被减less的模数大于可由结果types表示的最大值的数。 但是,两个标准都指出有符号整数溢出是未定义的行为。 再次,从C99标准( §3.4.3/1 ) 未定义行为的一个例子是整数溢出行为 有没有一个历史的(或更好的!)这种差异的技术原因?
我正在用C ++编写一个程序来查找b = c的所有解,其中a , b和c一起使用0-9的所有数字。 程序循环了a和b的值,并且每次在a , 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 有没有更好的方法来testing溢出? 我知道一些芯片有一个内部的标志,当溢出发生时,但我从来没有见过它通过C或C ++访问。