为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

尚方宝剑之说 2022-07-06 19:13:43
谷歌计算器可以计算的最小非零数似乎是 2^-1023。即 2^-1024 等于 0。在 JAVA 中,Double.MIN_VALUE 是 2^-1074。当在这里和互联网上阅读 JAVA 的 Double.MIN_VALUE 时,有很多提到 IEEE 754,但实际上没有一个说 2^-1074 是 IEEE 754 中定义的最小非零数。所以我的问题是:JAVA 的 Double.MIN_VALUE 与 IEEE 754 对最小非零数的定义有何关系?有这样的事情吗?当显然有这样的数字时,为什么谷歌的计算器不能计算小于 2^-1023 的数字?(我知道人们不会每天都使用它们,但编程语言仍然允许使用它们)在 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?我应该向 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 回答

?
慕侠2389804

TA贡献1719条经验 获得超6个赞

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

您应该仔细阅读关于 FP 数的优秀教程,例如每个程序员都应该了解的浮点运算知识。“正常”数字最小值为 2^-1023。但 IEEE-754 也有最小值为 2^-1074 的“次正规”(或非正规)数。这些数字可以更小,但会严重降低精度。

当显然有这样的数字时,为什么谷歌的计算器不能计算小于 2^-1023 的数字?(我知道人们不会每天都使用它们,但编程语言仍然允许使用它们)。

并非所有硬件都支持非正规数,并且当支持使用这些数字时,会带来很高的时间成本(例如,对于普通数的 pentium 操作符延迟约为 5,但如果结果或一个操作数低于标准,则可能 > 100) . 这可能是 google 不支持 subnormals 的原因(但这只是一个假设)。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 添加多少才能使其等于零?

只为自己减去它。


查看完整回答
反对 回复 2022-07-06
?
蛊毒传说

TA贡献1895条经验 获得超3个赞

  1. 与其“在这里和通过 Internet 阅读”,不如看一下 Javadoc:

    一个常数,保持类型 ... 的最小正非零值,double也等于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,只是按照Double#toString. 四舍五入Double.MIN_VALUE只是2*Double.MIN_VALUE碰巧朝不同的方向前进。

  4. -Double.MIN_VALUE,就像Double d您要添加的任何其他内容一样-d


查看完整回答
反对 回复 2022-07-06
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

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

IEEE 754 1074

您可以在 Wikipedia 上找到以下文章来很好地解释它:

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)。


查看完整回答
反对 回复 2022-07-06
  • 3 回答
  • 0 关注
  • 116 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信