error: invalid operands to binary % の原因と直し方
剰余演算子%をdouble型やfloat型に対して使おうとしたときに出るエラーです。%はint型などの整数型専用の演算子です。
エラーメッセージの読み方
main.c:7:22: error: invalid operands to binary % (have 'double' and 'double')
main.c- ファイル名
7- 行番号
22- 列番号 — この位置でgccが構文解析に失敗しました
invalid operands to binary % (have 'double' and 'double')- 内容 — 期待していたもの、または受け付けられなかったもの
このエラーが出る典型パターン
パターン1
1 #include <stdio.h> 2 #include <math.h> 3 4 int main(void) { 5 double a = 7.5; 6 double b = 2.0; 7 printf("%f\n", a % b ); ^ 8 return 0; 9 }
%はint型など整数専用の演算子で、double型には使えません。小数の余りを求めたいときはfmod()関数を使います。
直し方: a % b を fmod(a, b) にします。
パターン2
1 #include <stdio.h> 2 #include <math.h> 3 4 int main(void) { 5 double distance = 10.5; 6 double lap = 3.0; 7 printf("%f\n", distance % lap ); ^ 8 return 0; 9 }
distanceもlapもdouble型なので、%をそのまま使うとコンパイルエラーになります。fmod(distance, lap)が小数の余りを求める正しい書き方です。
直し方: distance % lap を fmod(distance, lap) にします。
パターン3
1 #include <stdio.h> 2 #include <math.h> 3 4 int main(void) { 5 double x = 9.2; 6 double y = 4.0; 7 printf("%f\n", x % y ); ^ 8 return 0; 9 }
整数の感覚で%を使うとdouble型では弾かれます。剰余が欲しい場合は必ずfmod()を使います。
直し方: x % y を fmod(x, y) にします。
パターン4
1 #include <stdio.h> 2 #include <math.h> 3 4 int main(void) { 5 double total = 20.5; 6 double part = 6.0; 7 printf("%f\n", total % part ); ^ 8 return 0; 9 }
合計と分割量の余りを求める場合も同じです。double型に%は使えず、fmod()が必要です。
直し方: total % part を fmod(total, part) にします。
パターン5
1 #include <stdio.h> 2 #include <math.h> 3 4 int main(void) { 5 double weight = 15.3; 6 double limit = 4.0; 7 printf("%f\n", weight % limit ); ^ 8 return 0; 9 }
重量の超過分を求めるような場面でも、%ではなくfmod()を使う必要があります。
直し方: weight % limit を fmod(weight, limit) にします。
よくある誤解
5.5 % 2.0のように小数の余りを求めたくなりますが、Cの%はビット単位の整数演算に近い操作で、浮動小数点数には定義されていません。小数の余りが欲しい場合はfmod()関数を使います。
実務での勘所
%が整数専用なのは、多くのCPUが整数の割り算を実行するとき、商と余りを1回の命令でまとめて計算するハードウェアを持っているためです。浮動小数点の演算ユニットにはこれに対応する「余りを直接返す」命令が無いため、Cは%を整数型だけに限定し、浮動小数点の剰余が必要な場合はfmod()というソフトウェアで計算するライブラリ関数を別途用意しています。演算子とライブラリ関数という違いは、ハードウェアが直接サポートしているかどうかの違いを反映しています。