1

私はFixedpointクラスを書いていますが、ちょっとした問題にぶつかりました...乗算、除算の部分、エミュレートする方法がわかりません。私は除算のオペレーターに非常に大まかな刺し傷を負いましたが、それは間違いだと確信しています。これまでのところ、次のようになります。

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ビットとして表されます)。整数部分である「値」についても同じことが言えます。'part'がその操作の1つで0xFFFFを超えると、上位16ビットが' value'に追加され、次に、下位16ビットのみが残るようにパーツがマスクされます。これは、初期化リストで行われます。

質問するのは嫌ですが、このようなドキュメントをどこで見つけることができるか、あるいは「トリック」やこれら2つの演算子の実行方法を誰かが知っているなら、私はそれをとても嬉しく思います!私は数学に関してはばかです、そして誰かが以前にこれをしなければならなかったことを知っています、しかしグーグルを検索することは私を約束の地に一度も連れて行かなかった...

4

3 に答える 3

2

Janが言うように、単一の整数を使用します。16ビット整数と小数部を指定しているように見えるので、プレーンな32ビット整数でこれを行うことができます。

「トリック」とは、数値を操作するときに数値の「フォーマット」がどうなるかを理解することです。あなたのフォーマットは16.16として記述されます。加算または減算しても、形式は同じままです。乗算すると、32.32が得られます。したがって、結果には64ビットの一時値が必要です。次に、>> 16シフトを実行して48.16形式にし、下位32ビットを使用して16.16で回答を取得します。

私は部門に少し錆びています-私がこのことを学んだDSPでは、可能な限り(高価な)部門を避けました!

于 2011-02-17T13:27:01.690 に答える
0

全体と小数部分を分けるのではなく、1つの整数値を使用することをお勧めします。加算と減算は直接整数に対応するものであり、最近ではすべての一般的なコンパイラで使用されている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(またはcstdintstd::名前空間に配置する)が使用可能である必要があるため、上記のタイプを使用できます。それ以外の場合はlong long、32ビットターゲットとlong64ビットターゲットにあります。
  • Windowsでは、常にlong longまたは__int64です。
于 2011-02-17T13:21:12.650 に答える
0

物事を稼働させるには、最初に(単項)を実装しinverse(x) = 1/x、次にとして実装a/ba*inverse(b)ます。おそらく、中間体を32.32形式で表現することをお勧めします。

于 2011-02-17T14:45:37.520 に答える