🤖

Arduinoのintはそんなにでっかくないぞ

2024/07/01に公開

大学でArduino Unoを使う講義のSAでヘルプをしていたときにみんなでハマったので、置いておきます。

問題のスケッチ

  int T = 1000; // 周期(ms)
  int D = 50; // デューティ比(%)

  //int delayHigh = D * T * 0.01; // -155
  //int delayHigh = D * T / 100; // -155
  int delayHigh = 0.01 * D * T; // 500
  Serial.println(delayHigh);

一番下のdelayHighは期待通りの値(500)が出力され、それ以外は-155が出力されます。

結論

単純にオーバーフローしてただけでした。C言語とかのノリで書くなという話ですね。
Arduinoでのint型は16bitなので-32768~32767までしか扱えません。対してC言語のintは32bitで-2147483648~2147483647の範囲の値を扱えます。(ただし16bitOSのときは16bitの範囲)

言語 int型の範囲
Arduino -32768~32767
C -2147483648~2147483647

今回のケースではD * Tをしているタイミングで50 * 1000 = 50000となるためオーバーフローして負値になってしまっていました。
普段Arduinoのスケッチを書かない学生はこの辺りがC言語などと同じと思いこんで、ハマってしまうのだと思います。また、OSなどの環境によってもintの扱いが異なる場合もあるようです。
静的型付けの言語を使うときは、型のことをちゃんと頭に入れておきましょう。。。

参考

https://www.arduino.cc/reference/en/language/variables/data-types/int/
https://www.javadrive.jp/cstart/var/index2.html
https://learn.microsoft.com/ja-jp/cpp/c-language/type-int?view=msvc-170

Discussion