Java:通过Float.floatToIntBits递增?

时间:2012-03-29 08:26:51

标签: java floating-point atomic

我需要以原子方式递增浮点值。我通过调用它上面的Float.floatToIntBits得到它的int值。如果我只是做一个i ++并将其转换回浮点数,它就不会给我预期的值。那我该怎么办呢?

(我正试图通过AtomicInteger创建一个AtomicFloat,因此这个问题)。

编辑:这就是我的所作所为:

Float f = 1.25f;
int i = Float.floatToIntBits(f);
i++;
f = Float.intBitsToFloat(i);

我想要2.25,但却获得了1.2500001。

2 个答案:

答案 0 :(得分:5)

原因是您从floatToIntBits获得的位代表

  1. 符号
  2. 指数
  3. 尾数
  4. 这样布局:

    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方法很有用。