0

マイクロコントローラーの倍率で値を複数にしたいのですが、浮動小数点値を使用できません。たとえば、値 170 を取得したら、これに倍率 ex を掛けます。0.00065 なので、結果は 0.1105 で、必要なのは 0.11 だけです。-500 から +500 までの値があります。不動点の問題であることは知っていますが、解決方法がわかりません。助けてくれてありがとう

4

2 に答える 2

1

入力が整数で、出力のみが固定小数点である必要がある場合、それはかなり単純です。

16.16固定小数点を使用しましょう。これは、16ビットの小数部と16ビットの整数があることを意味します。整数を固定小数点に変換するには、左に16ビットシフトする(または65536を掛ける)だけです。

入力は、、170または0xAAです。したがって、固定小数点表現はになります0xAA0000

0.00065を掛けたいと思います。これはになります0x002b

乗算するには、数値を乗算してからスケールの1つをキャンセルするか(両方の入力がスケーリングされるため、結果は2回スケーリングされます)、乗算する前にスケールの1つをキャンセルする必要があります。

0xaa0000 * 0x2b = 0x1c8e0000
0x1c8e0000 >> 16 = 0x1c8e

ただし、これはより大きな入力でオーバーフローする可能性があることに注意してください。500を使用しようとすると、32ビットより大きい値が生成されます。

入力が整数の場合は、シフトしないままにしておくことができます。そうしよう:

0xaa * 0x2b = 0x1c8e

同じ答えですが、シフトはありません。ただし、入力は明らかに整数のみにすることができます。

いずれにせよ、0x1c8eあなたの答えですが、65536分の1で表されます。その数値を10進数(7310)で除算し、65536で割ると、0.11154 ...が得られます。これは、必要な答えの近似値です。

あなたは固定点であなたが好きな分数/整数分割を選ぶことができます、そしてあなたは混ぜ合わせることさえできます。通常、入力または出力のいずれかを適切にシフトして、数学演算を実行するときに分割がどこにあるかを考慮する必要があります。対処すべき主な問題は、実行したい操作に対してオーバーフローまたはアンダーフローしないフォーマットを選択することです。

値を出力するには、ほんの少しの整数操作が必要です。

値を取りましょう0xaa1c8e。まず、16だけシフトして整数部分を取ります。これにより、0xaaが得られます。

ここで、0x1c8eである分数を取ります。必要な桁数に適切な量を掛けます。小数点以下2桁の場合、100を掛けます。それは0xb2778を与えます。それを16だけ戻します。これにより、0xbだけが残ります。

文字列:を使用してprintfを実行すると、"%d.%02d", 0xaa, 0xb「170.11」が表示されます。これは正しいです。

大まかな例を次に示します。

int a = (0.00065 * 65536 + 0.5); // Convert the float value to fixed point, with rounding.
int b = 170;

int m = b * a;

bool n = false;
if(m < 0) {m = -m; n=true;}
int i_part = m >> 16;
int f_part = m & 0xffff;
f_part *= 100;
f_part >>= 16;

printf("%s%d.%02d\n",n?"-":"",i_part,f_part);
于 2012-12-18T16:28:44.510 に答える
0

固定小数点を 2 つの整数で表し、操作を実行する必要がある場合は両方を使用します。たとえば、というように、numerator( ) と denominator( )0.11 = 11/100という 2 つの整数変数を使用できます。これらを組み合わせて、値に対応する有理数を表します。11100

于 2012-12-18T16:18:03.723 に答える