2012-03-29 75 views
3

我需要以原子方式增加浮點值。我通過調用Float.floatToIntBits來獲得它的int值。如果我只是做一個i ++並將其轉換回浮動狀態,它不會給我預期的價值。那麼我將如何去做呢?Java:通過Float.floatToIntBits增量?

(我試圖通過AtomicInteger創建一個AtomicFloat,因此這個問題)。

編輯:這裏是我所做的:

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

我想2.25,但得到1.2500001代替。

+1

預計什麼?實際結果是什麼?給一些更多的描述? – 2012-03-29 08:29:33

+0

如果你想舉一個你期望的和發生的事情的例子,這將有所幫助。這是完全可能的,這個問題符合你的期望。 – 2012-03-29 08:29:54

+2

「增加浮動」是什麼意思?給它添加1,或者獲得下一個更大的浮點值(添加一個ULP)? – 2012-03-29 08:44:50

回答

5

的原因是,你從floatToIntBits得到位代表

  1. 標誌
  2. 指數
  3. 尾數

佈局是這樣的:

Repr: Sign Exponent   Mantissa 
Bit: 31 30......23 22.....................0 

遞增在teger存儲與1這些領域不會受到1.

我試圖通過創建一個的AtomicInteger AtomicFloat,因此這個問題

我做正是這增加它代表的浮點值在回答這個問題:

添加功能由一個遞增的浮動,你可以複製the code of incrementAndGet from AtomicInteger(和改變從intfloat):

public final float incrementAndGet() { 
    for (;;) { 
     float current = get(); 
     float next = current + 1; 
     if (compareAndSet(current, next)) 
      return next; 
    } 
} 

(請注意,如果你想通過最小可能值遞增浮動,你取上述代碼和改變current + 1current +Math.ulp(current)。)

+0

感謝您的答案。但是您爲incrementAndGet顯示的代碼不會使用CAS操作,對(AtomicInteger的方式)?所以它必須以通常的方式同步? – shrini1000 2012-03-29 12:53:58

+0

我在我的答案中發佈的'incramentAndGet'方法打算包含在我在[其他答案]中描述的'AtomicFloat'類中(http://stackoverflow.com/questions/5505460/java-is-there-無atomicfloat或 - atomicdouble/5505512#5505512)。 – aioobe 2012-03-29 13:19:57

+0

哦,好的。得到它了。謝謝! – shrini1000 2012-03-30 02:46:07

2

原子部分可以頂上compareAndSet爲一個包裝類來實現,如圖aioobe的鏈路。 AtomicInteger的增量運算符就是這樣實現的。

增量部分是完全不同的問題。根據「增加浮點數」的含義,它要麼需要在數字中加1,要麼增加一個ULP。對於後者,在Java 6中,Math.nextUp方法就是您正在尋找的方法。爲了減少一個ULP,Math.nextAfter方法很有用。

+1

請注意,nextAfter需要額外的「虛擬」參數,例如「Float.MAX_VALUE」,而「Math.ulp」則直接給出了到下一個浮動的距離。 – aioobe 2012-03-29 08:47:14

+0

正如我剛看到的,'Math.nextUp(f)'(Java 6)返回'f + ulp(f)'的值,而不需要'nextAfter(f,INFINITY)'需要的額外參數,並且可能更快比原來計算'f + ulp(f)'要好。 – 2012-03-29 19:45:03