1

次のコードで正常な結果が得られないのはなぜですか?

void Motors::setCycleDutyA(int percentage) {
    Serial.println(percentage);
    Serial.println(pwmCycleDutyA);
    float x=percentage/100;
    Serial.print(x);
    pwmCycleDutyA = int(255*x);
    Serial.println(pwmCycleDutyA);
}

関数を呼び出すと:

Motors::setCycleDutyA(45);

次の結果が得られます。

45 255 0.000

45 0 0.000

45 0 0.000

何が恋しいですか?

4

3 に答える 3

5

ここ:

float x=percentage/100;

整数除算を実行しています (両方のオペランドが整数であるため)。これは、が より小さい0たびに結果が になることを意味します。それはあなたが得ている結果を説明しています。percentage100

次のように変更します。

float x=percentage/static_cast<float>(100);

または、次のようにします。

float x=percentage/100.f;
于 2013-03-20T14:05:00.887 に答える
3

問題はfloat x = percentage / 100percentageは のタイプintです。これは、 の両方の引数/が整数であることを意味し、したがって整数除算が実行されます。次に、結果は に変換されfloatます。

あなたはこれを求めている:

float x = percentage / 100.f;

または、タイプを に変更percentagefloatます。

于 2013-03-20T14:06:04.910 に答える
1

このような状況では、浮動小数点の使用を避ける傾向があります。このようなモーターを制御するコードは、浮動小数点を直接サポートしていない小さなマイクロコントローラーで実行されることが多いため、浮動小数点計算はソフトウェアでエミュレートされることがよくありますが、これは遅く、かなりの余分なコードを追加する可能性があります。

したがって、代わりに整数演算でこれを実行できるかどうかを検討してみます。シーケンスを見る:

float x=percentage/100;
pwmCycleDutyA = int(255*x);

これは基本的に次と同等です。

pwbCycleDutyA = percentage * 2.55;

かなりの数の目的のために、それを として扱うだけで十分percentage * 2.5です。これは、整数演算で非常に簡単にレンダリングできます。

pwbCycleDutyA = (percentage * 5) / 2;

これにより、生成できる値の範囲が 0..255 ではなく 0..250 に減少します。ただし、パーセンテージは から始まるためint、どのような場合でも 100 個の離散値しか生成できないことに注意してください。 (もしあれば)多くの違いを生む可能性があります。

ただし、乗数を 2.5 ではなく 2.55 にする必要があると確信している場合は、それも可能です。最も明白なのは、式を単純に並べ替えることです。100 で割ってから 255 を掛ける代わりに、最初に 255 を掛けてから 100 で割ります。

pwbCycleDutyA = (percentage * 255) / 100;

このような方程式を再配置する際に留意すべき主なことは、オーバーフローを防ぐことです。が 100 を超えることはないと仮定するとpercentage、かなり安全ですが、中間結果が を超えることはありません25500。これは、符号付き 16 ビット int (C で許可される最小値) に簡単に収まります。

于 2013-03-20T14:27:12.447 に答える