Why does Oracle claim java.util.Random.nextFloat() generates 2^24 possibilities and not 2^23?

Koo*_*sha 6 java random floating-point

According to the documentation for java.util.Random, the Java class implements nextFloat by next(24) / ((float)(1 << 24)) (ie. a random non-negative integer with 24 bits divided by 224). The documentation claims that all 224 possible values can be returned. They are between 0 (inclusive) and 1 (exclusive). However, I don't think that is true.

First, note that according to the IEC 559 (IEEE 754) standard, float has 23 fraction bits. But there is an implicit leading bit (to the left of the binary point) with value 1, unless the exponent is stored with all zeros. Therefore, it is true that there are a total of 224 values of type float that are between 0 (inclusive - not counting negative zero) and 1 (exclusive), but exactly half of these numbers are subnormal (all bits in the exponent are 0), which makes them all less than 2-126. Therefore, none of these numbers can be generated by the implementation. This is because they are all strictly smaller than 2-24 which is used in the implementation.

的布局float可以采用单精度浮点格式

那我想念的是什么呢?

Eri*_*hil 5

在区间[+0,1)中,存在127•2 23个float,而不是2 24。指数编码字段从0到126(含)之间的每种组合都有一个,有效位数编码字段中的每个值为23位。

形式为m •2 ?24的每个值,其中0?m <2 24是可表示的。这种形式的最小非零值是2 ?24,用指数代码103和有效码0表示。数学指数是代码103,减去偏差127等于?24,其数学有效值为1。

对于除m以外的任何m,令b为其前1位的位置编号(从0开始为低位)。然后 •2 ?24被编码在float与的指数代码b 103和一个有效位代码 •2 24?b?2 24。当m = 0时,将使用全零位进行编码。

这种形式的数字都不是次正规的。


Koo*_*sha 0

每个数字类型float有 23 个小数位和 8 个指数位。我们展示如何float精确表示0.b 1 b 2 b 3 ...b 24n形式的每个数字。设为使 b i 不为零的最小数。如果不 存在 ,则可以用 表示。否则,n = 2 -i 2 i 0.b 1 b 2 b 3 ... b 242 -i部分可以清楚地用 中的 8 位指数来表示。此外,部分2 i 0.b 1 b 2 b 3 ...b 24 的形式为1.b i+1 b i+2 ...b 24,其至多具有23个小数位。因此可以精确地表示为。iin=0floatfloatnfloat

剩下的就是统一生成 b 1 b 2 b 3 ... b 24形式的随机整数,然后将它们除以 2 24,这正是 Oracle 所建议的。