私はプログラミングに比較的慣れていないため、常に数学が苦手です。私は 16 ビット符号付きのプログラムを持っています。INT
-32,768 +32,768
これらの値を1-100
正側と-1 - -100
負側で表現して、作業しやすくしたいと思います。したがって、基本的に 100 は 32,768 に等しくなります。50 は 16,384 に等しくなります。など。どうすればこれを簡単に達成できますか? 私は C でプログラミングしていますが、これは何よりも数学の問題だと思います。
4 に答える
整数を作成しようとしている場合は、16 ビット整数値 (通常は a short
) で [-100, 100] の範囲を使用するだけでよいため、要件は奇妙に思えます。
10 進数の値を含めることも検討している場合は、[-100, 100] の範囲を非常にうまく表現できないことを考慮する必要があります...別の16ビット整数値からの16ビット整数値、あなたはそれを行うことができます
int16_t normalized = ( rawvalue / 327 ); // <--- scaled, rawvalue is int16_t
ただし、精度が低下し、特定の範囲の値にエイリアシングがあるため、これはあまり良くないようです.... float
aまたは aを格納できる場合、またはdouble
値 [-100, 100] をもう少し適切に保持できる場合:
double normalized = ( rawvalue * ( 32768.0 / 100.0 ) );
// float normalized = /*... */ Append "f" for "float" math instead on those constants
あなたの要件は...奇妙に思えますが、それがあなたのやり方です。幸運を!
編集:
最後の推奨事項として、プログラムの別の部分が 100 -> -100 を要求しない限り、範囲 [-1.0, 1.0] を使用または使用している場合は、操作float
がはるかに優れており、はるかに強力になる可能性があると言えます。サーバーに入る生の整数値を含む、他の入力と出力に入る数値のスケーリングなどを行うとき。(INT16)(0.75 * MAX_MOTOR_VALUE) は、100 から -100 で仕上げるよりもはるかに優れています。double
16 ビット整数は、-32767 から +32767 (非 2 の補数表現) または -32768 から +32767 (2 の補数表現) まで、最大で2 16 =65536 個の異なる値しか持つことができません。したがって、実際には 32767 を 100 に、-32767 を -100 に等しくする必要があります。
できることは次のとおりです。
int int2fixed(int x)
{
return x * 32767LL / 100;
}
int fixed2int(int x)
{
return x * 100LL / 32767;
}
最大値で割り、100 を掛けて整数に切り捨てます。例 (最大値除算と 100 による乗算を 1 ステップに組み合わせる):
int normalize(int a)
{
assert(a >= -32768 && a <= 32767)
return (int)ceil(a / 327.68);
}
彼女が忘れているすべての答えは、結果を 1..100 にほぼ均等に分散させる必要があるということです。そして、これらの答えは 100 に達することはありません。
int normalize(int a)
{
return (int)(a*101L/ 32769);
}