2010-08-04 87 views

回答

1

32位定點的定義可能會有所不同。定點的一般概念是,你有一些固定的位數和小數點(或二進制點)後的另一個固定位數。對於32位,最常見的分割可能是偶數(16之前,16之後),但根據目的不能保證。

就轉換過程而言,它也可能會出現一些變化 - 例如,如果輸入數字超出目標範圍,您可能需要執行許多不同的操作(例如,在某些情況下環繞可能是有道理的,但在其他情況下飽和可能是首選)。

1

定點類型是在小數點後面有固定數量的十進制/二進制位的定點類型。或者更一般地說,對於某個正整數N可以存儲1/N的倍數的類型。

在內部,定點數被存儲爲乘以縮放因子的值。例如,比例因子爲100的123.45存儲爲整數12345.

要將定點數的內部值轉換爲浮點數,只需除以縮放因子即可。要轉換另一種方式,請乘以縮放因子並四捨五入到最接近的整數。

3

一個非常簡單的轉換爲定點的例子,它展示瞭如何轉換和乘以PI by2。由此產生的結果被轉換回雙倍以證明在用整數計算時尾數不會丟失。

你可以很容易地用sin()和cos()查找表等擴展它。 如果您打算使用固定點來查找Java定點庫,我會推薦。

public class Fix { 

    public static final int FIXED_POINT = 16; 
    public static final int ONE = 1 << FIXED_POINT; 

    public static int mul(int a, int b) { 
     return (int) ((long) a * (long) b >> FIXED_POINT); 
    } 

    public static int toFix(double val) { 
     return (int) (val * ONE); 
    } 

    public static int intVal(int fix) { 
     return fix >> FIXED_POINT; 
    } 

    public static double doubleVal(int fix) { 
     return ((double) fix)/ONE; 
    } 

    public static void main(String[] args) { 
     int f1 = toFix(Math.PI); 
     int f2 = toFix(2); 

     int result = mul(f1, f2); 
     System.out.println("f1:" + f1 + "," + intVal(f1)); 
     System.out.println("f2:" + f2 + "," + intVal(f2)); 
     System.out.println("r:" + result +"," + intVal(result)); 
     System.out.println("double: " + doubleVal(result)); 

    } 
} 

OUTPUT

f1:205887,3 
f2:131072,2 
r:411774,6 
double: 6.283172607421875 
+0

+1表示乘法。兩個改進建議:提供將double轉換爲定點的四捨五入;並重寫'toString()',這樣可以很容易地打印定點值的正確解釋(然後可以在測試中使用它)。 – MatthewD 2010-08-05 06:11:28

16

的固定點數目是使用一定數目的一種類型爲整數部分的比特,一個實數的表示和所述類型的用於剩餘位小數部分。表示每個部分的位數是固定的(因此名稱,定點)。整數類型通常用於存儲定點值。

定點數字通常用於沒有浮點支持的系統,或者需要比浮點更多的速度。定點計算可以使用CPU的整數指令來執行。

32位定點數將存儲在32位類型中,如int

通常在每個比特整數類型(在這種情況下,無符號)將如下表示整數值2^N:

1 0 1 1 0 0 1 0  = 2^7 + 2^5 + 2^4 + 2^1 = 178 
2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0 

但是,如果類型是用來存儲一個定點值,則位被解釋略有不同:

1 0 1 1 0 0 1 0  = 2^3 + 2^1 + 2^0 + 2^-3 = 11.125 
2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4 

該示例中的固定點數目以上被稱爲4.4定點數,因爲有在整數部分4個比特,並在數的小數部分的4位。在32位類型中,定點值通常爲16.16格式,但也可以是24.8,28.4或任何其他組合。

從浮點值的定點值轉換涉及到以下步驟:

  1. 乘浮子由2 ^(分數位的數目爲類型),例如。 2^8 for 24.8
  2. 如果需要,將結果舍入(只需加0.5),並將其放置(或強制轉換爲整數類型),留下整數值。
  3. 將此值分配給定點類型。

顯然你可以在數字的小數部分失去一些精度。如果小數部分的精度很重要,定點格式的選擇可以反映這一點 - 例如。使用16.16或8.24而不是24.8。

負值也可以以同樣的方式,如果你的定點數需要進行簽名處理。

如果我的Java更強大,我會嘗試一些代碼,但我通常使用C編寫這樣的東西,所以我不會嘗試Java版本。此外,堆垛機的版本看起來不錯,除了小例外,它不提供四捨五入的可能性。他甚至向你展示瞭如何執行乘法(該轉變很重要!)

+0

+1爲這樣的'無名英雄'話題花費了太多時間。 – stacker 2010-08-04 20:22:17

+0

所有的答案都是正確的,如果你提供了一個解決方案,那麼你的答案可以被接受。幸運的是,我有這個,我打算把它放在這裏:int number = Float.floatToRawIntBits(floatNumber); – instcode 2010-08-20 18:08:17

+0

我正在學習這個固定點的東西..在你的例子中,應該10.125 * 10^4 = 178?它等於162。 – 2011-01-26 00:36:31