2

一部の学習演習と一部の趣味のプロジェクトとして、固定小数点演算を使用して AVR に Cooley-Tukey FFT アルゴリズムの独自の解釈を実装しています。私はこれまで固定小数点演算をあまり扱ったことがなく、実装の一部をどのように行うのが最善なのか疑問に思っています。この質問の要点は、関連する問題について正しく考えていることを確認するための要求だと思います。

CT アルゴリズムの心臓部には、次の方法 (疑似コード) での複素数値データに対する一連の乗算と加算が含まれます。

temp1 = cosine(increment)*dataRealPart[increment1] 
-sine(increment)*dataImaginaryPart[increment1]

temp2 = cosine(increment)*dataImaginaryPart[increment1] 
+ sine(increment)*dataRealPart[increment1]

dataRealPart[increment1] = dataRealPart[increment2] - temp1

etc.

コサインおよびサイン データは、S.XXX'XXXX 形式の 8 ビット符号付きバイナリ小数であり、入力データも SXXX.XXXX 形式の 8 ビット符号付きバイナリ小数であり、乗算は 16 ビット符号付き小数積を生成します。 . 私が見たように、サインとコサインの特に「悪い」値、およびデータの実部と虚部の場合、temp1 または temp2 は 16 ビットの符号付き整数の限界にかなり近くなります。
データの実数部と虚数部の両方が、たとえば b0111.1111 である場合、Wolfram Alpha で少し調べてみると、サインとコサインの値が「悪い」場合、出力は単純な値よりも最大 1.4 倍大きくなる可能性があることがわかります。正弦波の最大値に入力の最大値を掛けると、

たとえば、正弦引数が b0111.1111 で入力値が b0111.111 の場合、出力は b0111111.00000001、つまり 10 進数で 16129 になります。1.4 倍、約 22580 になります。これは、符号付き 16 ビット整数の正の範囲をオーバーフローしませんが、次の行では、これらの積が入力データに加算および減算され、ここでの入力データが 16 ビットに変換されると仮定します。 、オーバーフローが発生する可能性があります。

トレードオフのように見えます: データの内部処理分解能を上げて処理時間を増やすか、入力データを振幅よりも低くしてオーバーフローを引き起こし、信号対雑音比を低下させます。それは物のサイズについてですか?

4

2 に答える 2

1

1 つのオプションは、正弦値と余弦値を Q6 (10 進数の右側に 6 ビット) に減らすことです。これにより、+/-64 になります。精度を 1 ビット上げると、-1 は表現できますが、+1 は表現できません (つまり、+128)。また、乗算後、結果に 2 つの符号ビットが含まれます。これは、2 つの積の合計を問題なく加算できることを意味します。解像度の低下によるこの余分なビットにより、オーバーフローを実際に回避できるはずです。別のポイント - 複素数値が 1 の大きさ (real*real+img*img <=1) に制限されている場合、得られた 1.4 の数値とは対照的に、結果の合計は 1 を超えません。これは、sine が 1 であるためです。 、コサインはゼロです。基本的に、単位ベクトル (cos、sin) と複素数ベクトルのドット積をとっています。それを超えて、追加する前に 16 ビット製品を数ビット右にシフトすることができます。

最後に 1 点。多くの数値の合計を取得していて、結果が常に表現可能な範囲内にあることがわかっている場合は、中間結果のオーバーフローについて心配する必要はありません。最終的にはすべてうまくいくでしょう(破棄したビットの合計はとにかくゼロになります)。

于 2011-06-27T17:04:55.203 に答える