java - 为什么 Oracle 声称 java.util.Random.nextFloat() 生成 2^24 种可能性而不是 2^23?
问题描述
根据java.util.Random的文档,Java 类实现nextFloat
了next(24) / ((float)(1 << 24))
(即一个 24 位的随机非负整数除以 2 24)。该文档声称可以返回所有 2 24 个可能的值。它们介于 0(包括)和 1(不包括)之间。然而,我不认为这是真的。
首先,请注意,根据 IEC 559 (IEEE 754) 标准,float
有 23 个小数位。但是存在一个值为 1 的隐式前导位(在二进制点的左侧),除非指数以全零存储。因此,确实有 2 24个类型值float
介于 0(包括 - 不包括负零)和 1(不包括)之间,但是这些数字中恰好有一半是次正规的(指数中的所有位都是 0 ),这使得它们都小于 2 -126。因此,这些数字都不能由实现生成。这是因为它们都严格小于实现中使用的 2 -24。
的布局float
可以在Single-precision floating-point format中找到。
那么我错过了什么?
解决方案
在区间 [+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 ,令b为其前 1 位的位置编号(从 0 开始编号为低位)。然后m •2 -24被编码为b +103float
的指数代码和m •2 24- b -2 24的有效数字代码。对于m = 0,它被编码为全零位。
这种形式的数字都不是次常的。
推荐阅读
- kotlin - 如何在 Kotlin 的片段上显示吐司?
- php - Eloquent - 从多个模型中获取、合并和分页数据
- c# - 所有嵌套字典都具有相同的值?
- android - 将 mapbox 地图附加到 livedata
- react-native - 使使用 react-native-image-crop-picker 选择的图像成为 png
- ruby-on-rails - Rails Minitest 处理文件创建
- php - PHPMailer 错误:php_network_getaddresses:getaddrinfo 失败:LOCALHOST(XAMPP)中的名称解析暂时失败
- python - 如何仅使用新输入的第一个元素从时间序列模型中进行预测
- java - 没有有效的方法来禁用菜单 Copy / Past / Cut 吗?它一直显示java
- arrays - 对数组进行排序,以便对绝对值进行排序,并在负值之前打印正值