java中的向下舍入浮点转换

java中的向下舍入浮点转换,java,floating-point,primitive,floating-point-conversion,Java,Floating Point,Primitive,Floating Point Conversion,我的代码中有一行代码,如下所示: float rand = (float) Math.random(); Math.random()返回一个double,即=0.0,我建议使用double而不是float 我所发现的唯一的缺点通常只有在您拥有大量这些缺点时才会发挥作用,因为存储要求更高,而这里的情况似乎并非如此 如果必须使用float,那么您已经尝试过的解决方案可能是可用的最佳解决方案。一个基本问题是,将double转换为float时,如果精度降低,可能会导致1.0f 因此,强制浮点值在所需的

我的代码中有一行代码,如下所示:

float rand = (float) Math.random();

Math.random()返回一个double,即
=0.0
,我建议使用
double
而不是
float

我所发现的唯一的缺点通常只有在您拥有大量这些缺点时才会发挥作用,因为存储要求更高,而这里的情况似乎并非如此

如果必须使用
float
,那么您已经尝试过的解决方案可能是可用的最佳解决方案。一个基本问题是,将
double
转换为
float
时,如果精度降低,可能会导致
1.0f

因此,强制浮点值在所需的范围内

但是,您不必为此在代码中添加
if
语句,只需提供一个float random函数,它就可以为您执行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
(所有尾数位都设置为
1
)的指数乘数
2-1
),因此您可以在上面的
frandom()
函数中使用它而不是
0.0f


这是从我不久前编写的一个方便的小工具中收集到的,它在摆弄IEEE754浮点值时被证明是非常宝贵的。

如果您只想在
rand==1.0f
时取整,那么我支持@paxdiablo的答案。然而,听起来你对总是四舍五入没问题,只是想总是四舍五入。如果是:

从javadoc:

下一次停机(浮动f) 返回在负无穷大方向上与f相邻的浮点值

作为对你评论的回应——很好。为了避免这个问题,您可以简单地将语句包装在对
Math.abs()
的调用中,这将不会产生任何影响,除非
nextDown()
的结果为负

float rand = Math.abs(Math.nextDown((float)Math.random()));

是的,这基本上就是我已经拥有的。我想知道的问题是如何通过向下舍入到下一个值而不是最近的可用值来将double转换为float。如果
0.1
be
1.0
,小于
1.0f
的最大float是
0.99999994f
,但四舍五入小于
1.0f
的最大翻倍约为
0.99999997
,大约为千万分之一。这取决于对生成的数字的预期分布。使用0.9999994作为限制,将使最后一个值的概率为分布更均匀时的概率的一半。@Pascal,如果你是那种真正关心范围顶端或底端微小分布影响的人,那么你已经使用了另一种方法:-)@immibis,是的,应该是这样。修复,谢谢。这是一个很好的有用的发现!但是,如果Math.random()调用返回0.0,这将是不好的,因为它会将其推到0以下。我想如果我使用类似于“if(doubleRand!=floatRand)floatRand=Math.nextDown(floatRand);”的内容,那么-因此,只有当没有相等的等价物时,它才会下降一个值。这是已经提出的两种解决方案中最丑陋的解决方案,而且令人失望的是,它被选为公认的答案。此解决方案存在关于二次幂的混淆问题(一些值无法获得,特别是
0x1.fffff epxx
形式的值,而二次幂被过度表示)。@paxdiablo我同意-请参阅我上面的评论,我非常肯定
if
将是更好的解决方案,我只是在回答问题时玩得很开心(即sans
if
s)pascal,提出解决方案和回答一个非常具体的问题是两件非常不同的事情-这是后者。@PascalCuoq另一个答案并没有真正回答问题,我说我对解决我的具体问题不感兴趣,而是想知道如何找到最接近但不高于双精度的浮点值。有什么原因不能使用吗?
float rand = Math.abs(Math.nextDown((float)Math.random()));