【概要】
double は、浮動小数点数(実数)を保持するためのデータ型です。Arduinoプログラミングにおいて、センサーからのアナログ値の変換、PID制御の係数計算、あるいは正確な時間経過の計算など、整数型(int, long等)では表現できない連続的な数値を扱う際に使用されます。
この型は、単なる数値の保持だけでなく、演算子のオーバーロードを通じて算術演算、比較演算、代入操作をサポートします。
【仕様】
- データ型: 浮動小数点数(Floating-point number)
- メモリサイズ: アーキテクチャに依存(後述の「技術的特徴」参照)
- 初期状態: ローカル変数の場合は不定値、グローバル変数(静的領域)の場合は0.0で初期化される
- 精度: プラットフォームにより異なるが、一般に単精度(32-bit)または倍精度(64-bit)として定義される
【技術的特徴】
Arduino環境において最も重要な技術的特性は、「ターゲットマイコンのアーキテクチャによって、double の実質的な挙動が変化する」点にあります。
- AVRアーキテクチャ(Arduino Uno, Nano, Mega等)
- 重要: これらの環境では、
doubleはfloatと同一の32ビット単精度浮動小数点数として扱われます。 - 理由: 8ビットマイコンの演算能力の制約上、標準的な64ビット倍精度浮動小数点数のサポートがハードウェアレベルで提供されないためです。
-
影響:
doubleを使用してもfloatと同じ精度しか得られず、メモリ消費も同じになります。 -
ARM/ESP32アーキテクチャ(Arduino Due, ESP32, Nano Every等)
- これらの環境では、
doubleは標準的な64ビット倍精度浮動小数点数として実装されています。 -
影響: AVR環境と比較して高い精度が得られますが、演算速度やメモリ消費に影響を与える可能性があります。
-
IEEE 754 準拠
- ほとんどのArduino環境において、
double(およびfloat)は IEEE 754 標準に従います。これにより、NaN(非数)や無限大(Infinity)の扱いや、丸め誤差の挙動が定義されます。
【注意点】
- 演算速度のオーバーヘッド: 浮動小数点演算ユニット(FPU)を持たないマイコン(AVR等)では、
doubleの演算はソフトウェアエミュレーションによって行われます。これは整数演算と比較して極めて低速であり、ループ内での過度な使用は処理遅延の原因となります。 - 丸め誤差: 浮動小数点数はバイナリ形式で数値を近似して保持するため、
0.1 + 0.2 == 0.3のような比較が厳密には成立しない場合があります。比較の際はabs(a - b) < epsilonのような許容誤差を用いた判定が推奨されます。 - メモリ消費: 32ビットまたは64ビットのメモリを占有するため、メモリの極めて限定的な環境では、可能な限り整数型でのスケーリング(例:10.5Vを1050mVとして扱う)を検討してください。
- 割り込み内での使用: 浮動小数点演算は時間がかかるため、高頻度のタイマー割り込み内やISR(Interrupt Service Routine)内で複雑な
double計算を行うことは、ジッタや処理遅延を引き起こすリスクがあります。
【サンプルコード】
/*
* double型の精度と演算の基本例
* AVR環境ではfloatと同一の精度になることに注意
*/
void setup() {
Serial.begin(9600);
double sensorValue = 1023.0;
double voltage = 5.0;
// 演算の実行
double result = (sensorValue / voltage) * 0.75;
Serial.print("Result: ");
Serial.println(result);
// 比較演算の注意点
double val1 = 0.1;
double val2 = 0.2;
double sum = val1 + val2;
if (sum == 0.3) {
Serial.println("Exact match");
} else {
Serial.print("Difference: ");
Serial.println(abs(sum - 0.3));
}
}
void loop() {
// 待機
}
【活用例】
- PID制御のゲイン計算:
Kp,Ki,Kdなどの係数を精密に調整し、滑らかな制御出力を得る。 - センサーデータのスケーリング: アナログ入力値を物理単位(℃、Pa、m/sなど)に変換し、小数点以下の精度を維持する。
- 時間経過の計算:
millis()を用いた経過時間を秒単位(小数を含む)に変換し、移動平均フィルタや時間積分を行う。 - 科学計算・通信プロトコル: 複雑な数式を解く必要があるアルゴリズムや、高精度な実数値を要求する通信プロトコルへのデータ送信。


コメント