2025.06.30
計算順序による計算結果の違い
はじめに
具体的な計算例
a=123.1 b=151.017 c=0.133 d=10000.0
以下の2種類の計算を行いました。
a / b * c * d
a * c / b * d
a / b * c * d = 1084.1362230742236
a * c / b * d = 1084.1362230742234
となりました。小数点以下の最後の数字が違っています。
計算する順番によって、計算結果が違うことが確認できました。
Javaソースコード - 計算順序の違う2つの式で計算
DoubleError4.java
001 002 003 004 005 006 007 008 009 010 011 012 013
public class DoubleError4 { public static void main( String[] args ) { // aとbとcに任意の値を代入 double a = 123.1; double b = 151.017; double c = 0.133; double d = 10000.0; // 計算結果を出力 System.out.println( a / b * c * d ); System.out.println( a * c / b * d ); } }
コンパイル ソースコードが「ANSI」の場合
C:\talavax\javasample>javac -encoding sjis DoubleError4.java
コンパイル ソースコードが「UTF-8」の場合
C:\talavax\javasample>javac DoubleError4.java
実行
C:\talavax\javasample>java DoubleError4
実行結果
1084.1362230742236 1084.1362230742234
Javaソースコード - 計算の途中経過を出力
DoubleError5.java
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030
public class DoubleError5 { public static void main( String[] args ) { // aとbとcに任意の値を代入 double a = 123.1; double b = 151.017; double c = 0.133; double d = 10000.0; // 計算元の値を出力 System.out.println( "a=" + a ); System.out.println( "b=" + b ); System.out.println( "c=" + c ); System.out.println( "d=" + d ); System.out.println(); // 計算結果を出力 System.out.println( "a/b*c*dの途中経過を出力" ); System.out.println( "a/b=" + a / b ); System.out.println( "a/b*c=" + a / b * c ); System.out.println( "a/b*c*d=" + a / b * c * d ); System.out.println(); System.out.println( "a*c/b*dの途中経過を出力" ); System.out.println( "a*c=" + a * c ); System.out.println( "a*c/b=" + a * c / b ); System.out.println( "a*c/b*d=" + a * c / b * d ); } }
コンパイル ソースコードが「ANSI」の場合
C:\talavax\javasample>javac -encoding sjis DoubleError5.java
コンパイル ソースコードが「UTF-8」の場合
C:\talavax\javasample>javac DoubleError5.java
実行
C:\talavax\javasample>java DoubleError5
実行結果
a=123.1 b=151.017 c=0.133 d=10000.0 a/b*c*dの途中経過を出力 a/b=0.8151400173490402 a/b*c=0.10841362230742235 a/b*c*d=1084.1362230742236 a*c/b*dの途中経過を出力 a*c=16.3723 a*c/b=0.10841362230742234 a*c/b*d=1084.1362230742234
以下の2つの計算結果が不一致です。
a / b * c = 0.10841362230742235
a * c / b = 0.10841362230742234
以上です。