我需要以原子方式递增浮点值。我通过调用它上面的Float.floatToIntBits得到它的int值。如果我只是做一个i ++并将其转换回浮点数,它就不会给我预期的值。那我该怎么办呢?
(我正试图通过AtomicInteger创建一个AtomicFloat,因此这个问题)。
编辑:这就是我的所作所为:Float f = 1.25f;
int i = Float.floatToIntBits(f);
i++;
f = Float.intBitsToFloat(i);
我想要2.25,但却获得了1.2500001。
答案 0 :(得分:5)
原因是您从floatToIntBits
获得的位代表
这样布局:
Repr: Sign Exponent Mantissa
Bit: 31 30......23 22.....................0
将存储这些字段的整数与1递增,不会将其表示的浮点值增加1。
我正在尝试通过AtomicInteger创建一个AtomicFloat,因此这个问题
我在这个问题的答案中做到了这一点:
要添加将浮动递增1的功能,您可以复制the code of incrementAndGet
from AtomicInteger
(并从int
更改为float
):
public final float incrementAndGet() {
for (;;) {
float current = get();
float next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
(请注意,如果您想以最小可能值递增浮动,则可以使用上述代码并将current + 1
更改为current +
Math.ulp(current)
。 )
答案 1 :(得分:2)
原子部分可以在compareAndSet
上面为包装类实现,如aioobe的链接所示。 AtomicInteger
的增量运算符就是这样实现的。
增量部分是一个完全不同的问题。根据“增加一个浮点数”的含义,它要么你要在数字上加一个,要么递增一个ULP。对于后者,在Java 6中,Math.nextUp方法就是您正在寻找的方法。对于递减一个ULP,Math.nextAfter方法很有用。