我的代码中有一行,如下所示:
float rand = (float) Math.random();
Math.random()返回>=0.0
和<1.0
的双精度型。不幸的是,如果双倍距离rand
太近,则上面的广告可能会将1.0f
设置为1.0
。
有没有办法将double转换为浮点数,以便在找不到完全相等的值时,它总是向下舍入到下一个浮点值而不是最近的浮点值?
我不是在寻找有关RNG的建议,也没有寻找合作伙伴,例如跟进if(rand == 1.0f) rand = 0.0f;
。在我的情况下,该解决方案是解决我的问题的一种令人满意的方式,它已经实现。我只是想找出&#34;正确的&#34;这种数字转换的解决方案。
答案 0 :(得分:1)
我建议的选项是使用double
而不是float
。
我发现的唯一缺点通常只有在您拥有大量存储要求时才会发挥作用,因为存储要求更高,而且这似乎不是这种情况。
如果您必须使用float
,那么您已经尝试过的解决方案可能是最好的解决方案。转换double
到float
时精度损失可能会给您1.0f
这是一个基本问题。
因此强制浮动值在您想要的范围内。
但是,您不必为此使用if
语句来编写代码,只需提供一个浮动随机函数,为您执行grunt工作:
float frandom() {
float ret = 1.0f;
while (ret == 1.0f)
ret = (float) Math.random();
return ret;
}
或者,根据您的样本:
float frandom() {
float ret = (float) Math.random();
if (ret == 1.0f)
ret = 0.0f;
return ret;
}
然后用:
来调用它float rand = frandom();
对于Java(和其他人)而言,将Javascript能够将代码“注入”到类型中以便您可以将frandom()
实现到静态Math
中这将是一件好事。竞技场。这样你就可以使用:
float rand = Math.frandom();
但是,唉,这还不可能(据我所知,没有重新编译Java支持库,这似乎有点矫枉过正)。
顺便说一下,如果你正在寻找小于1的最大浮点值,它是0.99999994
(指数乘数2-1
,所有尾数位都设置为1
),因此,您可以在上面的0.0f
函数中使用{而不是frandom()
。
这是从我前段时间写的一个方便的小工具中收集的,这个工具在摆弄IEEE754浮点值时被证明是非常宝贵的。
答案 1 :(得分:1)
如果您只想在rand==1.0f
时进行回合,那么我会回答@ paxdiablo的回答。但是,听起来好像你总是四舍五入,只想总是围绕向下。如果是这样的话:
float rand = Math.nextDown((float)Math.random());
来自javadoc的:
nextDown(float f) 返回负无穷大方向上与f相邻的浮点值。
回应你的评论 - 好点。为了避免这个问题,您可以简单地将语句包含在Math.abs()
的调用中,除非nextDown()
的结果为负,否则这将不会产生任何影响。
float rand = Math.abs(Math.nextDown((float)Math.random()));