以下代码块将输出设为0.
public class HelloWorld{
public static void main(String []args){
int product = 1;
for (int i = 10; i <= 99; i++) {
product *= i;
}
System.out.println(product);
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么会这样吗?
我正在使用Long基元类型,每当我的'generateNumber'method调用时,它就会递增1.如果Long达到他的最大限制会发生什么?会抛出任何异常还是会重置为最小值?这是我的示例代码:
class LongTest {
private static long increment;
public static long generateNumber(){
++increment;
return increment;
}
}
Run Code Online (Sandbox Code Playgroud) 在几种现代编程语言(包括C++,Java和C#)中,该语言允许在运行时发生整数溢出,而不会引发任何类型的错误条件.
例如,考虑这个(人为的)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;
}
Run Code Online (Sandbox Code Playgroud)
如果调用此方法如下:
List<int> list = new List<int>();
list.Add(2000000000);
list.Add(2000000000);
int sum = sumList(list);
Run Code Online (Sandbox Code Playgroud)
sumList()方法中将发生溢出(因为intC#中的类型是32位有符号整数,并且列表中值的总和超过了最大32位有符号整数的值).sum变量的值为-294967296(不是值4000000000); 这很可能不是sumList方法的(假设的)开发人员所期望的.
显然,开发人员可以使用各种技术来避免整数溢出的可能性,例如使用类似Java的类型BigInteger,或者使用C#中的checked关键字和/checked编译器开关.
但是,我感兴趣的问题是为什么这些语言默认设计为允许整数溢出首先发生,而不是例如在运行时执行操作时引发异常,从而导致溢出.看起来这种行为有助于避免在编写执行可能导致溢出的算术运算的代码时开发人员忽略解释溢出可能性的情况下的错误.(这些语言可能包含类似"未经检查"的关键字,它可以指定允许发生整数溢出而不会引发异常的块,在开发人员明确意图该行为的情况下; C#实际上确实有这个. )
答案简单归结为性能 - 语言设计者不希望他们各自的语言默认具有"慢"算术整数运算,其中运行时需要做额外的工作来检查是否发生溢出,在每个适用的算术上操作 - 这种性能考虑超过了在无意溢出发生时避免"无声"故障的价值?
除了性能考虑之外,还有其他原因可以做出这种语言设计决策吗?
可能重复:
如何检查Java中的两个数字相乘是否会导致溢出?
假设我有一个Java类方法,它使用*和+操作.
int foo(int a, int b) {
... // some calculations with + and *
}
如何确保不会发生溢出foo?
我想我可以使用BigDecimal或替换所有+和*与"包装",如:
int sum(int a, int b) {
int c = a + b;
if (a > 0 && b > 0 && c < 0)
throw new MyOverfowException(a, b)
return c;
}
int prod(int a, int b) {
int c = a * b;
if (a > 0 && b > 0 && … 我知道编译器对整数文字进行隐式类型转换.例如:
byte b = 2; // implicit type conversion, same as byte b = (byte)2;
Run Code Online (Sandbox Code Playgroud)
如果范围溢出,编译器会给出错误:
byte b = 150; // error, it says cannot convert from int to byte
Run Code Online (Sandbox Code Playgroud)
当变量传递表达式时,编译器会给出相同的错误:
byte a = 3;
byte b = 5;
byte c = 2 + 7; // compiles fine
byte d = 1 + b; // error, it says cannot convert from int to byte
byte e = a + b; // error, it says cannot convert from int to byte …Run Code Online (Sandbox Code Playgroud) 这样做时:
int x = 100;
int result = 1;
for (int i = 1; i < (x + 1); i++) {
result = (result * i);
}
System.out.println(result);
Run Code Online (Sandbox Code Playgroud)
这显然是因为结果对于整数来说太大了,但我习惯于为溢出得到大的负数,而不是0.
提前致谢!
当我切换到这个:
int x = 100;
int result = 1;
for (int i = 1; i < (x + 1); i++) {
result = (result * i);
System.out.println(result);
}
Run Code Online (Sandbox Code Playgroud)
我得到这个.
为什么以下代码不会生成错误?
System.out.println((char) 2147483647);
Run Code Online (Sandbox Code Playgroud)
据Oracle数据类型,对于最大尺寸char为65,535.
- char:char数据类型是一个16位Unicode字符.它的最小值为'\ u0000'(或0),最大值为'\ uffff'(或65,535(含)).
在Java算术运算期间,JVM不会抛出下溢或溢出异常.很多时候,我们遇到了意想不到的结果,并想知道出了什么问题.
在.NET技术的情况下,我们有溢出和Undeflow异常.
所以我的问题是,为什么Java设计不会在算术运算期间抛出此异常
问题是:整数的反转数字.
例1:x = 123,返回321
例2:x = -123,返回-321
您是否注意到反转的整数可能会溢出?假设输入是32位整数,则反向1000000003溢出.你应该如何处理这类案件?
抛出异常?很好,但如果抛出异常不是一种选择呢?然后,您必须重新设计该功能(即添加一个额外的参数).
我搜索的网站的解决方案是:
public class Solution {
public static int reverse(int x) {
int ret = 0;
boolean zero = false;
while (!zero) {
ret = ret * 10 + (x % 10);
x /= 10;
if(x == 0){
zero = true;
}
}
return ret;
}
public static void main(String[] args) {
int s = 1000000003;
System.out.println(reverse(s));
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当s = 1000000003控制台打印-1294967295而不是3000000001.因此,如果我们不能使用异常,这个解决方案仍然无法解决溢出问题.这里有什么帮助?(虽然有一个提示:添加一个额外的参数,我仍然无法弄清楚我应该添加什么参数)