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

问题描述 投票:-1回答:3

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

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

当在这里和互联网上阅读有关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那么为什么(Double.MIN_VALUE + Double.MIN_VALUE)== 1.0E-323而不是9.8E-324,考虑到(4.9E-5 + 4.9E-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);

    }
}

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

java math ieee-754
3个回答
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) 。这可能是谷歌不支持次正规的原因(但这仅仅是一个假设)。 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添加多少才能使其等于零?

只是为它自己减去它。


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. 据记载,Double.MIN_VALUE是2 ^ -1074。它不等于4.9 * 10 ^ -324,它只是根据the specification of Double#toString这样打印。围绕Double.MIN_VALUE2*Double.MIN_VALUE恰好朝不同的方向发展。
  4. -Double.MIN_VALUE,就像你添加Double d的任何其他-d一样。

-1
投票

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

IEEE 754 1074

你可以在维基百科上找到以下文章来解释它:

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

双精度双精度数占64位。双精度:

  • 最接近零的正数和负数(由非正规化值表示,Exp字段中的所有0和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)。

© www.soinside.com 2019 - 2024. All rights reserved.