JAVA的Double.MIN_VALUE,IEEE 754和Google的计算器?

时间:2019-02-24 07:28:04

标签: java math ieee-754

似乎Google计算器可以计算的最小非零数字是2 ^ -1023。即2 ^ -1024等于0。

在JAVA Double中,MIN_VALUE是2 ^ -1074。

在此处和整个Internet上阅读有关JAVA的Double.MIN_VALUE的信息时,有很多提到IEEE 754的内容,但没有一个实际上说2 ^ -1074是IEEE 754中定义的最小的非零数字。

所以我的问题是:

  1. JAVA的Double.MIN_VALUE与IEEE 754的定义有何关系? 最小的非零数字?真的有这样的事吗?
  2. 为什么Google的计算器无法计算的数字小于 2 ^ -1023何时显然有这样的数字? (我知道人们不会 每天都使用它们,但编程语言仍然允许使用它)
  3. 在JAVA中,如果Double.MIN_VALUE == 4.9E-324,那么考虑(4.9E-5 + 4.9E),为什么(Double.MIN_VALUE + Double.MIN_VALUE)== 1.0E-323而不是9.8E-324 -5)== 9.8E-5?
  4. 要使Double.MIN_VALUE等于零,我应该加多少?

这是我针对这些问题制作的程序:

public class Lecture {
    public static void main(String[] args) {

        double min = Double.MIN_VALUE;
        double max = Double.MAX_VALUE;
        double minPlusOne = min + 0.0001;
        System.out.println("Min + 1: " + minPlusOne);
        System.out.println("Double.MIN_VALUE: " + min);
        System.out.println("Double.MIN_VALUE: " + max);
        double myMin = Math.pow(2, -1074);
        System.out.println("2^-1074: " + myMin);
        System.out.println("Double.MIN_VALUE == 2^-1074: "  + (min == myMin));
        System.out.println();

        System.out.println("Changed Min:" + (min + min));

        double a = 4.9E-5;
        double b = a + a;
        System.out.println(b);

    }
}

编辑:按要求,删除后续问题。

3 个答案:

答案 0 :(得分:1)

  

JAVA的Double.MIN_VALUE与IEEE 754对最小非零数字的定义有何关系?真的有这样的事吗?

您应该仔细阅读有关FP编号的良好教程,例如what every programmer should know about floating point arithmetic。 “正常”数字的最小值为2 ^ -1023。但是IEEE-754也具有“次正规”(或非正规)数字,其最小值为2 ^ -1074。这些数字可能会更小,但会大大降低精度。

  

为什么Google的计算器显然不能计算出小于2 ^ -1023的数字? (我知道人们并非每天都在使用它们,但是编程语言仍允许使用它。)

并非所有硬件都支持非正规数,使用这些数字支持非正规数时会带来的时间成本(例如,在奔腾运算符上,普通数的延迟约为5,但是可以>如果结果或一个操作数是次正规的,则为100。这可能就是Google不支持次态(但这只是一个假设)的原因。 FP库和硬件可以将次正规数视为零。

  

在JAVA中,如果Double.MIN_VALUE == 4.9E-324,那么为什么(Double.MIN_VALUE + Double.MIN_VALUE)== 1.0E-323而不是9.8E-324,考虑到(4.9E-5 + 4.9E -5)== 9.8E-5?

打印值四舍五入并以二进制显示。 2 ^ -1023的整数部分的精确值的小数比4.9多得多。和它的两倍相同。这只是显示问题。

  

我应该在Double.MIN_VALUE中添加多少才能使其等于零?

只需将其自身减去。

答案 1 :(得分:0)

  1. 查看“ Javadoc”就足够了,而不是“在这里和通过互联网阅读”:

      

    A constant holding the smallest positive nonzero value of type double... and also equal to Double.longBitsToDouble(0x1L).

    即它的最后一位是1,其余位是0。

  2. 2 ^ -1023实际上不是那里的最小值,您可以将Double.MIN_VALUE作为(2^-1023)/2^51获得。不知道为什么Google的开发人员让2^-1024返回0,您必须要问他们。

  3. 如记录所示,
  4. Double.MIN_VALUE为2 ^ -1074。它不是等于4.9 * 10 ^ -324的 ,而是根据the specification of Double#toString像这样打印出来的。 Double.MIN_VALUE2*Double.MIN_VALUE的舍入只是朝不同的方向进行。

  5. -Double.MIN_VALUE,就像您添加Double d的任何其他-d一样。

答案 2 :(得分:-1)

您可以将这些搜索词输入任何搜索引擎中,而不是“阅读并通过Internet”:

  

IEEE 754 1074

您可能会在Wikipedia上找到以下文章,对其进行了很好的解释:

https://en.wikipedia.org/wiki/IEEE_754-1985#Double_precision

  

双精度   双精度数字占用64位。在双   精度:

     
      
  • 最接近零的正数和负数(在Exp字段中为全零的非正规化值,在Fraction字段中为二进制值1的非正规化值表示)

         

    ±2 ^ −1074≈±4.94066×10 ^ −324

  •   
  • 最接近零的正负归一化数字(在Exp字段中用二进制值1表示,在小数字段中用0表示)

         

    ±2 ^ −1022≈±2.22507×10 ^ −308

  •   
  • 距离零最远的有限正数和有限负数(用Exp字段中的2046和分数字段中的全1表示)

         

    ±(1-2−−53)×2 ^ 1024≈±1.79769×10 ^ 308

  •   

https://en.wikipedia.org/wiki/IEEE_754#Basic_and_interchange_formats

  

请注意,在上表中,列出的最小指数是针对正常数字的;特殊的次普通数字表示法可以表示更小的数字(但会损失一些精度)。例如,binary64中可以表示的最小正数为2 ^ −1074(因为1074 = 1022 + 53-1)。

相关问题