1

我在寫一個定點類,但遇到了一點障礙...乘法,除法部分,我不知道如何模擬。我對師的操作員進行了非常粗魯的刺探,但我相信這是錯誤的。這是它到目前爲止的樣子:C++:仿真定點除法/乘法

class Fixed 
{ 
    Fixed(short int _value, short int _part) : 
     value(long(_value + (_part >> 8))), part(long(_part & 0x0000FFFF)) {}; 

    ... 

    inline Fixed operator -() const // example of some of the bitwise it's doing 
    { 
     return Fixed(-value - 1, (~part)&0x0000FFFF); 
    }; 

    ... 

    inline Fixed operator/(const Fixed & arg) const // example of how I'm probably doing it wrong 
    { 
     long int tempInt = value<<8 | part; 
     long int tempPart = tempInt; 
     tempInt /= arg.value<<8 | arg.part; 
     tempPart %= arg.value<<8 | arg.part; 
     return Fixed(tempInt, tempPart); 
    }; 

    long int value, part; // members 
}; 

我......我不是一個很好的程序員,哈哈!

該類的「部分」是16位寬(但表示爲長32位,因爲我認爲它需要在可能的溢出之前在它們被固定之前)的空間,並且相同的值爲整數部分。當「部分」在其中一個操作中超過0xFFFF時,最高的16位被添加到「值」,然後該部分被屏蔽,因此只剩下最低的16位。這是在init列表中完成的。我不想問這個問題,但如果有人知道我在哪裏可以找到類似這樣的文檔,甚至只是'訣竅'或如何做這兩個操作員,我會很高興的!我是一個昏昏沉沉的數學,我知道有人不得不這樣做/之前問這個,但搜索谷歌有一次沒有帶我去承諾的土地...

+0

這功課嗎?你基本上試圖模仿浮點數學,但沒有使用浮點數字符號?你看過IEEE如何處理這個問題嗎? – 2011-02-17 12:43:49

+0

@Zac可悲的是,從來沒有去過編程學校或什麼都沒有,因爲你可以告訴!這是一個非常糟糕的嘗試,以避免在我正在做的2D物理引擎中進行浮點運算。但我現在正在搜索IEEE,所以我會看到! – 2011-02-17 12:48:46

+0

@Zac:OP正在談論'固定'點多重分割,而不是'浮動'點,這是有區別的。 http://en.wikipedia.org/wiki/Fixed-point_arithmetic – 2011-02-17 12:50:14

回答

2

正如Jan所說,使用一個整數。由於它看起來像是指定了16位整數和小數部分,所以可以用一個普通的32位整數來完成。

「訣竅」是要了解當您對其進行操作時,數字的「格式」會發生什麼。你的格式將被描述爲16.16。當您添加或減少時,格式保持不變。當你乘,你得到32.32 - 所以你需要一個64位的臨時值的結果。然後你做一個>> 16位移到48.16格式,然後在16.16位取最低的32位來得到你的答案。

我對這個部門有點生疏 - 在DSP中,我學到了這些東西,我們儘可能地避免了(昂貴的)部門!

0

我建議使用一個整數值而不是單獨的整體和小數部分。比加法和減法是直接在integeral同行,你可以簡單地使用64位的支持,這是所有常見的編譯器有這些天:

  • 乘法:

    operator*(const Fixed &other) const { 
        return Fixed((int64_t)value * (int64_t)other.value); 
    } 
    
  • 司:

    operator/(const Fixed &other) const { 
        return Fixed(((int64_t)value << 16)/(int64_t)other.value); 
    } 
    

64位整數是

  • 關於gcc,stdint.h(或cstdint,它們將它們放置在std::名稱空間中)應該可用,因此您可以使用上面提到的類型。否則,它在32位目標上爲long long,在64位目標上爲long
  • 在Windows上,它始終是long long__int64
0

要啓動並運行,首先需要執行(一元)inverse(x) = 1/x,然後執行a/b作爲a*inverse(b)。您可能想要將中間體表示爲32.32格式。