4

ルックアップ テーブルを利用する正弦関数の基本的な固定小数点の変形を作成しました (FPU なしの AVR マイクロ コントローラーをターゲットにしています)。私の実装は、 math.hの浮動小数点ペンダントのように、負の値と 2π を超える値も受け入れます。

したがって、指定された値を 0 ~ 2π の範囲 (つまり、対応する固定小数点) にマップする必要があります。正の引数の場合、C の組み込み剰余演算子%を使用して簡単にトリムできます。これは負の値のオプションではないため、次の (明白な) アプローチを使用しています。

    unsigned int modulus = (a - (INT_FLOOR(a / b) * b) + b) % b;

abは整数型の値であり、INT_FLOOR() は (a/b) の小数部分が切り捨てられるというヒントとしてのみ使用されます。この式は、計算されたモジュラス (テーブル配列のインデックスとして使用される) が常に正であること、および負の引数も対応する正の値にマップされることを保証します (両方向の位相シフトを維持します)。

このアプローチに関する私の問題は、5 つ以上の算術演算が含まれるため、過度に複雑に見えることです。私が見逃しているより効率的なアプローチはありますか?

4

2 に答える 2

4

整数の引数が π の倍数になるようにスケーリングされていない限り (たとえば、65536 は 2π を意味します)、2π は無理数であり、2π を法とする任意の削減は次のようにスケールアップするエラーを導入するため、引数の削減を試みるのはおそらく見当違いです。リダクションの結果全体がエラーになるまでの期間の数。これは実際には、多くの浮動小数点トリガーの実装で深刻な問題です。

引数の削減をまったく行わないか、ラジアンではなく 2 の累乗に基づく角度スケールを使用することをお勧めします (たとえば、0x10000 または 0x1000000 は 2π または 360 度に対応します)。次に、引数の削減は単一のビット単位の and 演算になります。

于 2012-05-03T23:32:02.777 に答える
0

それほどきれいではありませんが、あなたの式は正しいと思います。

2 の累乗を作成bすると、一部の操作はビット マスクで実行できます。次のようなもの:

unsigned int modulus = (a - (a & ~(b-1)) + b) & (b-1);

定数またはマクロの場合bは、かなり最適化する必要があります。

于 2012-05-03T22:45:15.013 に答える