-2

我试图很好地理解 Java 的原始数据类型。我已经有了一个很好的概述,并且我了解有符号整数值是如何存储在 Java 中的,以及如何判断/计算字节、短、整数或长数据类型的范围。

因此,当查看 Java 数据类型 int 时,我知道它是一个 32 位有符号值,因此我可以准确地知道一个 int 类型可以存储多少不同的“状态”以及该数据类型的范围是什么(即 2^ 32 种不同的状态,范围从 -2^31 到 +(2^31)-1 或大致 -2e+9 到 +2e+9)。

但是,在查看数据类型 float 时,我需要一些帮助。我了解 Java 的浮点数据类型是 32 位类型(就像 int 一样),因此我假设它也可以存储总共 2^32 种不同的状态。但是,当我查看此表(http://www.javacamp.org/javaI/primitiveTypes.html)中给出的数字时,我不明白这种数据类型如何存储大约 -3e 范围内的浮点数+38 到 3e+38(这已经比 int 可以覆盖的范围大得多)加上介于两者之间的所有单精度浮点小数 - 只有 32 位。

谁能解释一下浮点数是如何存储的以及为什么它“看起来”可以在相同的位数内存储比 int 更多的信息(这对我来说几乎是不可能的)?也许你可以给我指出一个很好的阅读或告诉我我在哪里犯了一个逻辑错误。

4

2 回答 2

2

诀窍是意识到 a甚至float 不能准确地保存 -3e+38 到 3e+38 范围内的所有整数。“相邻”浮点值之间的差异取决于大小:对于接近 0 的浮点值,相邻值之间的差异;对于非常大的值(正或负),差异可能非常大。

基本上一个浮点数包括:

  • 一个符号 - 正面或负面
  • 尾数或有效位(请参阅下面的注释) - 一串二进制数字,有效地
  • 指数-将尾数左移或右移的二进制位数

a 中的尾数float是 23 位长,指数是 8 位 - 所以你只会得到 23(或归一化为 24)重要信息位,但它们可以向左移动很多(形成一个巨大的数字) 或正确很多(形成一个很小的数字)。规范化还有一些其他相关的细节,但这是基本思想。

有关更多信息,请参阅我的面向 .NET 但仍与 Java 相关的关于二进制浮点的文章,以及Jeffrey Sax的一篇文章。

于 2013-09-29T12:45:40.143 回答
1

为简单起见,我将放弃所有的小玩意和 upls 的东西。让我们看一下以 10 为底的 10 位数字(在这种情况下是无符号的,但相当可扩展)。它可以存储从 0 到 9999999999 的数字。现在,让我们将其中的 2 个数字转换为指数,就像浮点数一样。现在,我们可以从 1x10 -99到 99,999,999x 10^99。显然范围更大

请注意,我们最多会丢失较小的数字。例如,对于不是指数的 8 位数字,999,999,999,999,999,991 和 999,999,999,999,999,992 将以相同的方式被截断,因为这些数字不适合 8 位数字。他们都是 999,999,99x10 17

于 2013-09-29T12:45:11.747 回答