【问题标题】:What explains the range of a double in java?什么解释了 java 中双精度的范围?
【发布时间】:2021-02-07 16:02:26
【问题描述】:

我正在学习编程入门课程(java 中),我很想了解为什么 java 中原始数据类型的范围是这样的。当谈到像字节这样的整数数据类型时,似乎很容易理解为什么它只接受 -128 到 127 的值;一个字节的大小为 8 位,最多可以包含 256 个值,因此我们可以为这 256 个值中的每一个分配一个自然数,我相信这就是幕后发生的事情。它还解释了为什么排除 128:我们有 128 个负数、127 个正数和零。这些加起来已经有 256 个。 [1,256] 和 [-128,128] 之间没有双射。

这个想法对于所有类似整数的数据类型的范围都是有意义的,但是当涉及到浮点时,人们会看到一些奇怪的范围。例如 double 的范围是 [-2^{1074},(2-2^{-52})2^{1023}]。为什么会这样?


我为繁琐的符号道歉,显然我不能在这里使用乳胶。

【问题讨论】:

标签: java floating-point integer


【解决方案1】:

浮点值和整数值是一样的——可用的位数。

一个IEEE双长浮点值有64位,用法如下:

符号位:1 位
指数:11 位
有效位精度:52 位

有效位是二进制小数,因此最大值(所有位设置)略小于一。

指数的值为 0 到 2047,或 -1024 到 +1023。这为您提供了 2 到 -1024 到 2 到 +1023 的大致范围(实际上它更小,因为有几个值是为特定用途而保留的)。

Wikiipedia for more exact details

【讨论】:

  • 减 1:有效位精度:53 位,52 位被显式编码。
  • 明白了,但这绝对是介绍材料;近似不是不合适的。 (Knuth 中有一些话,我记不清了,关于他的材料包含出于教育目的的谎言 - 并不是我将自己与 Knuth 进行比较)
【解决方案2】:

Java 使用 IEEE-754 binary64 格式。在这种格式中,1 位表示符号(+ 或 - 取决于该位是 0 还是 1),8 位用于指数,52 位用于有效位的初级编码。 53 位有效数字的一位通过指数编码。

指数字段的值范围从 0 到 2047。2047 保留用于无穷大和 NaN。 0 用于次正规数。值 1 到 2046 用于普通数字。在此范围内,E的指数字段值表示指数e = E-1023。所以e的最小值是1−1023 = -1022,最大值是2046−1023 = 1023。指数字段值0也代表E的最小值em>,-1022。

53 位有效数字表示二进制数字ddddddd2,其中第一个d 如果指数字段为 0,则为 0,如果指数字段为 1 到 2046,则为 1。“.”后面有 52 位,它们由主有效位字段给出。

S为符号位域,E为指数域的值,F为初级有效数的值字段为整数。那么表示的值为:

  • 如果E是1到2046,(-1)S • 2E- 1023 • (1 + F•2-52),
  • 如果E为0,(-1)S • 2-1022 • (0 + F•2-52)。

现在我们可以看到,当S为1,E为0,F为1时表示最小的正数(000000000000000000000000000000000000000000000000000012)。那么表示的值为 (-1)0 • 2-1022 • (0 + 1•2-52) = +1 • 2 -1022 • 2-52 = 2-1074.

S为1,E为2046,F为252时表示最大有限数>-1(1111111111111111111111111111111111111111111111111112)。那么表示的值为 (−1)0 • 22046−1023 • (1 + (252−1)•2−52 = +1 • 21023 • (1 + 1 − 2−52) = 21023 • (2 1 - 2-52) = 21024 - 2971

【讨论】:

  • "53 位有效数字的一位通过指数进行编码。"描述隐含位的有趣且正确的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-27
  • 2017-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多