Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Float和Double数据类型中的溢出和下溢_Java_Overflow_Underflow - Fatal编程技术网

Java Float和Double数据类型中的溢出和下溢

Java Float和Double数据类型中的溢出和下溢,java,overflow,underflow,Java,Overflow,Underflow,我创建了以下代码来测试Float和Double Java数值数据类型的下溢和溢出: // Float Overflow & Underflow float floatTest = Float.MAX_VALUE; floatTest++; out.println("Float Overflow: " + Float.MAX_VALUE + " + 1 = " + floatTest); floatTest = Float.MIN_VALUE; floatTest--; out.print

我创建了以下代码来测试Float和Double Java数值数据类型的下溢和溢出:

// Float Overflow & Underflow
float floatTest = Float.MAX_VALUE;
floatTest++;
out.println("Float Overflow: " + Float.MAX_VALUE + " + 1 = " + floatTest);
floatTest = Float.MIN_VALUE;
floatTest--;
out.println("Float Underflow: " + Float.MIN_VALUE + " - 1 = " + floatTest);
out.println("");

// Double Overflow & Underflow
double doubleTest = Double.MAX_VALUE;
doubleTest++;
out.println("Double Overflow: " + Double.MAX_VALUE + " + 1 = " + doubleTest);
doubleTest = Double.MIN_VALUE;
doubleTest--;
out.println("Double Underflow: " + Double.MIN_VALUE + " - 1 = " + doubleTest);
out.println("");
有人能解释一下我在结果中看到的奇怪值吗:

当我用byte、short、int和long进行类似的测试时(代码如下):

// BYTE Overflow & Underflow
byte byteTest = Byte.MAX_VALUE;
byteTest++;
out.println("Byte Overflow: " + Byte.MAX_VALUE + " + 1 = " + byteTest);
byteTest = Byte.MIN_VALUE;
byteTest--;
out.println("Byte Underflow: " + Byte.MIN_VALUE + " - 1 = " + byteTest);
out.println("");

// SHORT Overflow & Underflow
short shortTest = Short.MAX_VALUE;
shortTest++;
out.println("Short Overflow: " + Short.MAX_VALUE + " + 1 = " + shortTest);
shortTest = Short.MIN_VALUE;
shortTest--;
out.println("Short Underflow: " + Short.MIN_VALUE + " - 1 = " + shortTest);
out.println("");

// INTEGER Overflow & Underflow
int intTest = Integer.MAX_VALUE;
intTest++;
out.println("Integer Overflow: " + Integer.MAX_VALUE + " + 1 = " + intTest);
intTest = Integer.MIN_VALUE;
intTest--;
out.println("Integer Underflow: " + Integer.MIN_VALUE + " - 1 = " + intTest);
out.println("");

// LONG Overflow & Underflow
long longTest = Long.MAX_VALUE;
longTest++;
out.println("Long Overflow: " + Long.MAX_VALUE + " + 1 = " + longTest);
longTest = Long.MIN_VALUE;
longTest--;
out.println("Long Underflow: " + Long.MIN_VALUE + " - 1 = " + longTest);
out.println("");
结果如预期:

有人能解释一下Java float和double中的溢出和下溢,以及为什么我会看到上面的结果吗?

这些“奇怪”的结果并不是Java特有的。只是相关IEEE标准定义的浮动比大多数人想象的要复杂得多。但在具体结果上:
Float.MIN_值
是最小的正值Float,因此非常接近于0。因此
Float.MIN_值-1
将非常接近-1。但由于-1左右的浮点精度大于该差值,因此结果为-1。至于
Float.MAX_值
,该值周围的浮点精度远大于1,添加1不会改变结果

浮点溢出 将
1
添加到
Double.MAX\u VALUE
Float.MAX\u VALUE
不能代表足够的值,以避免由于精度错误而向下舍入。在
Double.MAX_值时,由于尾数有53位,因此,该值相当大

System.out.println("Math.ulp(Double.MAX_VALUE) is " + Math.ulp(Double.MAX_VALUE));

1.9958403095347198E292
这个值是2971

您需要添加一个表达式,该表达式至少会产生这么多的溢出到
无穷大
。我说“收益至少这么多”,因为我可以通过添加2970使其溢出,但2969没有效果

doubleTest += Math.pow(2.0, 969);

1.7976931348623157E308

看起来2970四舍五入到2971以添加到
Double.MAX_VALUE
,但2969四舍五入到
0
,对总和没有影响

对于
浮点值
,也会发生类似的过程,尽管值并没有那么高

浮点下溢 这只是一个无穷小的值减一,实际上是减一。这不是暗流

doubleTest = Double.MIN_VALUE;
doubleTest /= 2;

0.0
下溢发生在指数(而不是值)太低而无法表示时,因此
0.0
结果。除以
2
得到下溢

doubleTest = Double.MIN_VALUE;
doubleTest /= 2;

0.0
整数/长溢出/下溢
这些都是期望值,因为您知道这些值“环绕”到值范围的另一端。

您的结果不一定非同寻常,只是浮动通常非常具体,并且您的请求非常接近。我在使用双数据类型时也遇到过类似的问题。只需仔细检查,确保您的代码符合预期。

您看到的是java基本数据类型的正确范围值。浮动类型的下溢与整数类型的下溢不同。对于浮动类型,下溢意味着“我们非常接近于零,当我们做算术时,我们的值很可能变得无关紧要并完全消失”。对于整数类型,underflow意味着“我们在尽可能小的整数上,所以当我们做算术时,我们有可能陷入尽可能大的整数”必读:谢谢,@Andreas,我已经相应地更新了我的答案。
doubleTest = Double.MIN_VALUE;
doubleTest /= 2;

0.0