【概要】
abs() 関数は、引数として与えられた数値の絶対値(Absolute Value)を計算し、戻り値として返す関数です。数学的な定義 $|x|$ に基づき、負の数であれば符号を反転させ正の数として返し、正の数またはゼロであればそのままの値を返します。
組み込みシステムにおいては、センサーデータの差分計算、距離の算出、信号処理における整流処理などで頻繁に使用される基本的な算術演算関数です。
【仕様】
| 引数 | int, long, short, float, double など(型に応じたオーバーロードが存在) |
| 戻り値 | 引数と同一のデータ型での絶対値 |
| 計算量 | O(1) |
| 標準ライブラリ | Arduino環境では標準Cライブラリ (stdlib.h, math.h) に依存 |
【技術的特徴】
-
関数オーバーロード:
Arduino(C++)環境では、引数となるデータ型に応じて適切な関数が呼び出されます。例えば、整数型にはabs(int)、浮動小数点型にはfabs(double)(またはabsのオーバーロード)が対応します。 -
ハードウェアレベルの挙動:
- 整数型: コンパイラ最適化により、ビット反転と加算(例:
abs(x) = (x ^ (x << 1)) - (x << 1)等の変形)や、単純な条件分岐命令として実装されます。 - 浮動小数点型: FPU(Floating Point Unit)を搭載したMCU(ESP32, STM32等)では専用命令が、非搭載のMCU(Arduino Uno等)ではソフトウェアライブラリによる近似計算が行われます。
- 整数型: コンパイラ最適化により、ビット反転と加算(例:
-
計算原理:
論理的には「値が0未満であれば -1 を掛ける」という処理ですが、オーバーフローを考慮した最適化が行われています。
【注意点】
-
INT_MIN の例外処理(重要):
2の補数表現を用いるシステムにおいて、符号付き整数の最小値(例:16bit intの-32768)の絶対値は、正の最大値(32767)を超えます。そのため、abs(INT_MIN)を実行した場合、型を拡張しない限り、予期しない値(多くの場合、元の負の値)が返る、あるいは未定義の動作となります。 -
型変換の副作用:
int型の変数をfloat型のabs()に渡す際、あるいはその逆の際に意図しない精度の欠落や、型変換によるオーバーフローが発生する可能性があるため、型の一貫性に注意が必要です。 -
割り込みへの影響:
abs()自体は極めて軽量な処理であるため、割り込みコンテキスト内での使用による遅延(レイテンシ)は無視できる範囲ですが、浮動小数点演算を含む場合は計算コストに注意が必要です。
【サンプルコード】
void setup() {
Serial.begin(9600);
}
void loop() {
// 整数型の絶対値
int val1 = -50;
int abs_val1 = abs(val1);
Serial.print("Integer abs(-50): ");
Serial.println(abs_val1);
// 浮動小数点型の絶対値
float val2 = -12.34f;
float abs_val2 = abs(val2);
Serial.print("Float abs(-12.34): ");
Serial.println(abs_val2);
// 注意点:INT_MIN の挙動(環境に依存)
int min_val = INT_MIN;
int abs_min = abs(min_val);
Serial.print("INT_MIN abs: ");
Serial.println(abs_min);
delay(5000);
}
【活用例】
-
距離計算(差分の絶対値):
2つのセンサー間の距離、あるいは目標値と現在値の偏差を計算する際に使用します。int error = abs(current_pos - target_pos); -
信号の整流(Rectification):
交流信号のような正負を繰り返す波形から、振幅成分のみを抽出する処理に使用します。 -
PID制御:
PID制御において、エラーの大きさを判定する際や、不感帯(Deadband)の判定に使用されます。 -
ベクトル演算:
2次元座標 $(x, y)$ から、各軸方向の絶対的な変位を算出する際に利用されます。


コメント