1
特定の処理と計算のためにawkを使用するbashの関数を持っていて、数値を含む2つの変数の減算結果常に機能するとは限りません。場合によってはawk:2つの変数の減算が不正確な結果を残す非常に小さな残差(e-15)を与える
私はこの(compare.sh)を実証するための一例のコードを作った(サイズe-15で)二つの変数の減算後に残ったいくつかの非常に小さな数を残すことは、AWKのように思える
#!/bin/bash
run_compare() {
awk ' BEGIN {
a = 4.5
#a = 3.75
b = 0.15
match_a = 3
# // print start values and heading //
printf ("\nStart value: %s\n", a)
printf ("Substract value: %s\n", b)
printf ("\n\033[4m A: B: C: is C <= %+s?\033[0m\n", match_a)
# // Loop and substract A with B //
for(i=0;i<26;i++) {
printf ("%+4s - %+4s = ", a, b)
a = a - b
printf ("%+6s", a)
if (a <= match_a) {
printf (" YES\n")
} else {
printf (" NO\n")
}
}
}'
}
run_compare
このスクリプトの出力がされます、
$ ./compare.sh
Start value: 4.5
Substract value: 0.15
A: B: C: is C <= 3?
4.5 - 0.15 = 4.35 NO
4.35 - 0.15 = 4.2 NO
4.2 - 0.15 = 4.05 NO
4.05 - 0.15 = 3.9 NO
3.9 - 0.15 = 3.75 NO
3.75 - 0.15 = 3.6 NO
3.6 - 0.15 = 3.45 NO
3.45 - 0.15 = 3.3 NO
3.3 - 0.15 = 3.15 NO
3.15 - 0.15 = 3 YES
3 - 0.15 = 2.85 YES
2.85 - 0.15 = 2.7 YES
2.7 - 0.15 = 2.55 YES
2.55 - 0.15 = 2.4 YES
2.4 - 0.15 = 2.25 YES
2.25 - 0.15 = 2.1 YES
2.1 - 0.15 = 1.95 YES
1.95 - 0.15 = 1.8 YES
1.8 - 0.15 = 1.65 YES
1.65 - 0.15 = 1.5 YES
1.5 - 0.15 = 1.35 YES
1.35 - 0.15 = 1.2 YES
1.2 - 0.15 = 1.05 YES
1.05 - 0.15 = 0.9 YES
0.9 - 0.15 = 0.75 YES
0.75 - 0.15 = 0.6 YES
これは、すべての罰金ですが、私が代わりに4.5の例3.75に(a)の値を開始するために変更した場合、その後の奇妙な何かが起こっている、
$ ./compare.sh
Start value: 3.75
Substract value: 0.15
A: B: C: is C <= 3?
3.75 - 0.15 = 3.6 NO
3.6 - 0.15 = 3.45 NO
3.45 - 0.15 = 3.3 NO
3.3 - 0.15 = 3.15 NO
3.15 - 0.15 = 3 NO # // Incorrect: This should be YES //
3 - 0.15 = 2.85 YES
2.85 - 0.15 = 2.7 YES
2.7 - 0.15 = 2.55 YES
2.55 - 0.15 = 2.4 YES
2.4 - 0.15 = 2.25 YES
2.25 - 0.15 = 2.1 YES
2.1 - 0.15 = 1.95 YES
1.95 - 0.15 = 1.8 YES
1.8 - 0.15 = 1.65 YES
1.65 - 0.15 = 1.5 YES
1.5 - 0.15 = 1.35 YES
1.35 - 0.15 = 1.2 YES
1.2 - 0.15 = 1.05 YES
1.05 - 0.15 = 0.9 YES
0.9 - 0.15 = 0.75 YES
0.75 - 0.15 = 0.6 YES
0.6 - 0.15 = 0.45 YES
0.45 - 0.15 = 0.3 YES
0.3 - 0.15 = 0.15 YES
0.15 - 0.15 = 1.4988e-15 YES # // Incorrect: Should be 0 //
1.4988e-15 - 0.15 = -0.15 YES
なぜこのようなことが起こっているのか、回避策があるのか、何か問題があったのか分かっている人はいますか?私は検索しようとしましたが、この特定のまたは類似の事例を説明するものは見つかりませんでした。
代わりに、浮動小数点演算のBR /オラ
[すべてのプログラマが浮動小数点演算について知っておくべきこと](http://floating-point-gui.de/) – choroba