我了解 random.Float() 带回 0.0 到 0.999 之间的浮点数...
但出于未知原因,几乎相同的代码带来了 2 个不同的答案。
我想了解为什么 t1 可以随机 1.0 而 t2 不能。
我试图检查一个类似的问题,但找不到任何类似的东西
Random rand = new Random();
for (int i = 0; i < 1000000000; i++) {
float t1 = 0.9f + rand.nextFloat() * 0.1f;
float t2 = 0.1f + rand.nextFloat() * 0.9f;
if (t1 == 1.0f) {
System.out.println("t1 " + t1);
}
if (t2 == 1.0f) {
System.out.println("t2 " + t2);
}
}
没有错误消息我只是不明白为什么 t1 有时会带回 1.0 数字而 t2 不会。
编辑:t1 生成最大值 0.999... *0.1 即 0.0999... + 0.9 = 0.9999... t2 生成最大值 0.999... *0.9 即 0.8999... + 0.1 = 0.9999 ... 两者都应该不一样吗?
差异的主要原因是对于任何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
(如果用实数计算)的最大值是 0.1• d距离 1,但t2
0.9• d距离 1。
Random.nextFloat
返回最大值为 16777215/16777216 的一个原因是它是float
小于float
1 的最大值。格式的精度使得可表示值之间的步长为 1/16777216。这意味着该邻域中的两个可表示值分别为 16777215/16777216 和 1,d是它们之间的距离。我们上面的计算表明 的最大值离 1t1
仅 0.1• d。因此,当它四舍五入为 时float
,1 是最接近的float
。
相比之下, 的最大值t2
为 0.9• d距 1。这意味着它距 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。本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句