SDCC(リトルエンディアン)コンパイラを使用している場合、この算術の何が問題になっているのですか?
-
24-09-2019 - |
質問
私はCプログラミングで非常に新しいですし、私は私のMCU用のファームウェアアプリケーションに取り組んでいます。私はKEILコンパイラ(ビッグエンディアン)を使用していたときに、このメソッドは、罰金を働いていたが、私はSDCCコンパイラ(リトルエンディアン)に切り替えたときに、それが正常に動作していません。誰かが私は???間違ってやっているかを説明してくださいすることができます。
ターゲットデバイスは、8051アーキテクチャに基づいているシリコン・ラボラトリーズC8051F320である。
unsigned **int** MotorSteps = 0; //"Global" variables
unsigned **int** MotorSpeed = 0;
bit RampUp()
{
float t = 0;
t = MotorSteps;
if ( t < 51 )
{
t = (1-((50 - t)/50))*15;
t = (t * t);
MotorSpeed = 100 + t;
return 0;
}
else return 1;
}
を追加しました: まず、私は今の符号なし整数型であることをMotorStepsとMotorSpeedを変更しました。を トン= 0.031497(小数つまり私のデバッガでは、何らかの理由で、私はif文の行にブレークポイントを設定している場合、この関数MotorSteps = 00の最初の入り口で、tはまた0に割り当てられます必要がありますので、しかし、デバッガショー)。私は六角に表示するデバッガを切り替えると、T = 0x3d010300。これトンが割り当てられていないばかりでしているようだ...
解決
もしMotorSteps = 49そして、
(50 - 49) / 50 = 0.02
次の
(1 - 0.02) = 0.98
と
0.98 * 15 = 14.7
としてTを設定します。この値を二乗
t = 14.7 * 14.7 = 216.09
は最後に、unsigned char型にフロートバックからの暗黙的な変換はMotorSpeed変数をオーバーフロー
MotorSpeed = 100 + 216.09...// Implicitly converts the float t to an unsigned char of 216
100 + 216 = 316の合計は、もちろん、unsigned char型をオーバーフローし、あなたが316から256 = 60で終わる。
このは関係なく、コンパイラのはおそらく不要な動作です。
他のヒント
これは、tが取得されることはありませんようにです 割り当てられた...
コンパイラが宣言
にT 0の値を割り当てるための理由はありませんfloat t = 0;
それはすぐに次の行にMotorStepsに割り当てられますので、。私の推測では、オプティマイザが宣言でゼロへの割り当てを無視し、デバッガは単にTがスタック上に配置されているメモリの初期化されていない値が表示されます。
あなたは完全に式を退治するとランプ値のためのテーブルのルックアップを使用して検討する必要があります。唯一の51の値があるように見えますので、テーブルは比較的小さくなります。値を検索するためのコードの多くのの迅速8051上の浮動小数点ライブラリを使用するよりもなります。
#define NUM_RAMP_STEPS 51
unsigned char MotorSteps = 0; //"Global" variables
unsigned char MotorSpeed = 0;
const unsigned char RampTable[NUM_RAMP_STEPS] = {...appropriate values...};
bit RampUp()
{
if ( MotorSteps < NUM_RAMP_STEPS )
{
MotorSpeed = RampTable[MotorSteps];
return 0;
}
else return 1;
}
あなたがそれらを必要としない限り、少なくとも、あなたは浮動小数点ライブラリを避けるために、floatではなく、あなたの整数をテストすることができ...
unsigned **int** MotorSteps = 0; //"Global" variables
unsigned **int** MotorSpeed = 0;
bit RampUp()
{
if ( MotorSteps < 51 )
{
float t = MotorSteps;
t = (1-((50 - t)/50))*15;
t = (t * t);
MotorSpeed = 100 + t;
return 0;
}
else return 1;
}
なぜあなたはBEからLEに切り替えたのですか?ターゲット・デバイスのアーキテクチャは何ですか?そして、それを何であるかの方法により、?
とにかく、質問へ。私は、変換が行われるときに問題が来ることをかなり確信しています。電卓でラインで、あなたのコード行をトレースし、数字が予想外になったときに探してみてくださいしてみます。