2011-12-14 68 views
2

我需要一個算法來做C中的無符號定點除法。我最多可以使用32位字。定點無符號除法C

我想盡量減少表示整數部分所需的位數,同時可以使用[0..15]範圍內的數字。所以顯然最小的比特數是4.問題是我發現的算法只能使用5比特。因爲它將餘數與除數進行比較,然後將餘數進行移位直至大於除數,如果除數具有最高有效位1,則該算法將不做任何操作,而是移位餘數(它永遠不會更大)。這裏的代碼:

int divu(int a, int b){ 
    int pt_int, r, pt_frac=0; 
    int i; 

    pt_int = ((unsigned) a/b) << BITS_FRAC; 
    r = (unsigned) a%b; 

    for (i=BITS_FRAC; i>=0; i--){ 
     if ((unsigned) r < b) 
     r <<= 1; 
     else{ 
     r -= b; 
     pt_frac += 01 << i; 
     r <<= 1; 
     } 
    } 
    return pt_int + pt_frac; 
} 

如果你有一個解決方案,但不想了解代碼,請發佈它。 :)

例子:

我們希望在2,這將導致0.75分1.5。假設我們使用整數部分的4位和分數的28位。所以,我們的數字是十六進制是:

1.5: 0x18000000 
2:  0x20000000 
result: 0x0c000000 
+0

這氣味像功課 – 2011-12-14 14:47:06

+2

我不明白的問題。你能提供一個示例輸入,以及預期的和實際的輸出。 – 2011-12-14 14:55:03

+1

如果你想分解無符號的值,你能做的最少就是在你的函數聲明中這麼說。 – unwind 2011-12-14 15:12:38

回答

1

正如指出的here(例如:乘以一個常數的倒數的整數),那麼您可以使用倒數乘法重新實現你的部門。之後,您應該能夠用4位來表示整數部分。

0

你有4.28定點數,你想除以4.28的數字。您可以通過從分母中減去分子的精度來找到除法後的精度,因此直分可以得到4.28-4.28 = 0--無有效位。顯然這是行不通的。

 1.5 [4.28] 0x18000000 
/2.0 [4.28] 0x20000000 
    = 0? [0.00] 0x00000000 

做這將是(由2^28相乘),然後做一個64位鴻溝,促進分子以8.56的理想方法:

     . . . . 
    1.5 [8.56] 0x180000000000000 
/2.0 [4.28]  0x20000000 
    = 0.75 [4.28]  0x0c000000 

如果你真的可以」使用64位數字,那麼你唯一的選擇是減少分母。 例如,您可以通過2^14

 1.5 [4.28] 0x18000000 
/2.0 [2.14]  0x8000 
    = 0.75 [2.14]  0x3000 

將使用一半的精度,然後您可以通過相同的因子相乘的結果要回一個4.28數量:0x3000 *(1<<14) = 0x0c000000

你失去一些精度這種方式,但不使用更大的分子是不可避免的。例如 5.0/3.0 = 1.66667 = 0x1AAAAAA [4.28],但
((5.0<<28)/(3<<14))<<14 = 0x1AAA8000 [4.28] = 1.66662