ヒント:millisのパラメーターはunsigned longであることに注意してください。プログラマーがintなどの他のデータ型を使用して計算しようとすると、エラーが生成される場合があります。
どんな数学?ミリで作業しているときに除外される他の種類の処理は何ですか?
誰かがこのステートメントを明確にしたり、例を挙げたりできますか?
ヒント:millisのパラメーターはunsigned longであることに注意してください。プログラマーがintなどの他のデータ型を使用して計算しようとすると、エラーが生成される場合があります。
どんな数学?ミリで作業しているときに除外される他の種類の処理は何ですか?
誰かがこのステートメントを明確にしたり、例を挙げたりできますか?
回答:
C / C ++で方程式を記述するときはいつでも、操作されるデータ型は方程式の出力に非常に現実的な影響を与えます。
各タイプのようにint
、float
とunsigned long
異なる動作を持っている、と記憶するには、スペースの一定量を取ります。
int
(arduinoの場合)は16ビットで格納され、その値の半分は負の数に、1/2は正の値に、1つの値は0に、それぞれ-2 ^ 15(-32,768)の範囲で与えられます。 + 2 ^ 15-1(32,767)に。
unsigned long
(arduino上)は32ビットですが、負として指定されているものはありません。その範囲は0〜2 ^ 32-1(4294967295)です。
どんな数学?ミリで作業しているときに除外される他の種類の処理は何ですか?
問題の核心は、millisの戻り時間が32767を超えてintに保存しようとしたときに、arduinoがそれを実行できなかったint
ことです。計算のタイプは、これは立入禁止です。特定の演算ではなく、より小さなデータタイプで行われる計算です。多分これらの例は役立つでしょう:
int i = 32767;
Serial.println(i);
//No problems here; it fits just fine
32767
i = 32767 + 1;
Serial.println(i);
//Oh no, the value didn't fit
-32768
unsigned long fake_millis = 42000;
i = fake_millis;
Serial.println(i);
//This is an example of millis going past an int
-23536
i = -10;
unsigned int j = i;
Serial.println(j);
//no way to put a negative number in an unsigned value
65526
uint32_t k = fake_millis;
Serial.println(k);
//unsigned long is a uint32_t on arduino; this works great!
42000
これを実装する方法は本当に非常に天才です。これらの数値がどこから来ているのか、なぜそれらがそうなるのかについて興味がある場合は、2の補数表現の同じ説明を調べる必要があります。
unsigned long
、さまざまなプラットフォーム(x86など)によって変わる可能性があり、uint32_t
常にどこでも32の符号なしビットになります。
32767 + 1
)は未定義の動作を生成することに注意してください。これはほとんど常に悪いことです。他の例は、信頼できる文書化された動作です。
millis()
unsigned long
Arduinoでは32ビットの符号なし整数であるを返します。次にunsigned int time = millis() - 1000
、のようなことを行おうとすると、それを16ビットの符号なし整数に格納しようとしますunsigned int
。16ビット整数は32ビット値を保持できません。
C仕様 6.3.1.3項によれば、上位16ビットは破棄されます。
可能であれば、millis()
出力をa に保持し、unsigned long
ビットが失われないことが確実である場合にのみ、ビットの少ないデータ型を使用してください。
Cの明示的なキャストの詳細については、https://stackoverflow.com/a/13652624/1544337を参照してください。
uint32_t
たまたまunsigned long
オンarduino を返すと言う方が正しいと思いませんか?
unsigned long
。
int time = millis() - 1000
)である場合、結果は同様です:上位16ビットが破棄されます。今回のC標準では、結果は実装定義であり、動作は整数の実装定義動作(4番目の箇条書き)に関するgccドキュメントで指定されています。