釣られた
https://qiita.com/higashi_nc/items/9a5ea00415a008f06843 に釣られて読みました。
2行でまとめると以下のような内容です。
- 10進数の0.1や0.2は浮動小数点数で表すとピッタリ0.1や0.2にはならずに誤差が出る
- 浮動小数点数の扱いを理解して、より堅牢なプログラムを作成することを願っています。
え?結局どうしたらいいの?という感想だけ残ったので各言語での浮動小数点数同士の比較の方法を ChatGPT に教えてもらいました。
結局どうしたらいいのか
基本的に浮動小数点数同士の差がある程度の誤差より小さければ同じ数である、という判定をすればいいようです。
今回の回答には含まれませんでしたが、おそらく言語によっては浮動小数点数同士の比較をする専用のライブラリなどもあるかと思われます。
Python
import math
a = 0.1
b = 0.2
if math.isclose(a + b, 0.3, rel_tol=1e-5):
print("等しい")
else:
print("等しくない")
Go
package main
import (
"fmt"
"math"
)
// FloatEquals 浮動小数点数が等しいかどうかを判定する
func FloatEquals(a, b, epsilon float64) bool {
return math.Abs(a - b) < epsilon
}
func main() {
var a, b float64 = 0.1, 0.2
var result float64 = a + b
// 0.3 と比較する場合
if FloatEquals(result, 0.3, 0.0001) {
fmt.Println("等しい")
} else {
fmt.Println("等しくない")
}
}
C
#include <stdio.h>
#include <math.h>
int floatEquals(double a, double b, double epsilon) {
return fabs(a - b) < epsilon;
}
int main() {
double a = 0.1;
double b = 0.2;
double epsilon = 0.00001;
if (floatEquals(a + b, 0.3, epsilon)) {
printf("等しい\n");
} else {
printf("等しくない\n");
}
return 0;
}
PHP
function floatEquals($a, $b, $epsilon = 0.00001) {
return abs($a - $b) < $epsilon;
}
$a = 0.1;
$b = 0.2;
if (floatEquals($a + $b, 0.3)) {
echo "等しい\n";
} else {
echo "等しくない\n";
}
Java
public class Main {
public static boolean floatEquals(double a, double b, double epsilon) {
return Math.abs(a - b) < epsilon;
}
public static void main(String[] args) {
double a = 0.1;
double b = 0.2;
double epsilon = 0.00001;
if (floatEquals(a + b, 0.3, epsilon)) {
System.out.println("等しい");
} else {
System.out.println("等しくない");
}
}
}
JavaScript
function floatEquals(a, b, epsilon = 0.00001) {
return Math.abs(a - b) < epsilon;
}
let a = 0.1;
let b = 0.2;
if (floatEquals(a + b, 0.3)) {
console.log("等しい");
} else {
console.log("等しくない");
}