1 回答
TA贡献1884条经验 获得超4个赞
差异的主要原因是对于任何x < 1, .9 + x •.1 大于 .1 + x • .9,并且返回值小于 1。对于它返回的最大值,前一个表达式是这样的接近 1,将其四舍五入产生 1,但后一个表达式离 1 更远,将其四舍五入产生下一个低于 1 的表达式。Random.nextFloat
float
float
float
返回的最大值Random.nextFloat
为Random.nextfloat
16777215/16777216。让M成为这个最大值,让d = 1 − M = 1/16777216。
如果我们t1
用实数计算,它的最大值就是0.9 + M •.1。= .9 + (1− d )•.1 = 1− .1• d。类似地,t2
将是 .1 + M •.9 = .1 + (1- d )•.9 = 1-.9• d。
t1
现在我们可以很容易地看到(如果用实数计算)的最大值与 1 相差 .1• d,但t2
与 1 相差 .9• d。
最大值Random.nextFloat
返回 16777215/16777216 的一个原因是它是float
小于 1 的最大值float
。格式的精度是这样的,导致 1 的可表示值之间的步长是 1/16777216。这意味着该邻域中的两个可表示值是 16777215/16777216 和 1,d是它们之间的距离。我们上面的计算表明 的最大值与1 相差t1
仅 .1• d。因此,当它四舍五入为 时float
,1 是最接近的float
。
相反,最大值与 1 相差t2
.9• d 。这意味着它与 16777215/16777216 仅相差 .1• d。所以,当它四舍五入时float
,16777215/16777216 是最接近的float
。
那就是使用实数运算。下面,我将展示浮点运算。它有舍入误差,但事实证明这些误差很小,不会改变结果。
在 中Java
,源文本.1f
和.9f
被转换为float
,产生 0.100000001490116119384765625 和 0.89999997615814208984375。使用 执行表达式中的算术运算double
,然后将结果四舍五入float
以赋值给t1
或t2
。
t1
可以计算出最大的:
nextFloat
代入yields的最大回报值0.9f + 16777215./16777216 * 0.1f;
。算术计算
double
得出 0.999999971687793642871611154987476766109466552734375。转换为
float
1,因为该double
值介于 0.999999940395355224609375(下一个较低的float
值)和 1(下一个较高的值)之间,并且它更接近后者而不是前者。
t2
可以计算出最大的:
nextFloat
代入yields的最大回报值0.1f + 16777215./16777216 * 0.9f;
。算术计算
double
得出 0.99999992400407933246242464520037174224853515625。转换为
float
收益率 0.999999940395355224609375。
添加回答
举报