はじめMath! Javaでコンピュータ数学

第11回 引き算はコンピュータの弱点[後編]

この記事を読むのに必要な時間:およそ 2 分

前回は浮動小数点数のエラー・誤差のうち,「オーバーフロー/アンダーフロー」「桁落ち」について学びました。今回は演習として,「桁落ち」とその回避方法を経験してみましょう。

問題:二次方程式の解の公式で,桁落ちを生じないように式変形しましょう。

解の公式

(1)a=0.25,b=20,c=0.1 の場合,float型で計算するとどの程度桁落ちを発生するでしょうか。プログラムを作成して実行してみましょう。

(2) 式変形を行い,桁落ちを生じない形の式を導きましょう。

(3) 式変形後の式をプログラムに追加して再計算し,桁落ちが改善されているか確認しましょう。

解説

問題:二次方程式の解の公式で,桁落ちを生じないように式変形しましょう。

(1)a=0.25,b=20,c=0.1 の場合,どの程度桁落ちを発生するでしょうか。プログラムを作成して実行してみましょう。
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
//filename : Ketaochi.java
import java.io.*;
class Ketaochi {
  public static void main(String[] args)
                          throws IOException {
    float a = 0.25f;
    float b = 20f;
    float c = 0.1f;
    float x1 = 0f;
    float x2 = 0f;

    x1 = ( -b + (float) Math.sqrt(b*b-4*a*c) ) / (2 * a) ;
    x2 = ( -b - (float) Math.sqrt(b*b-4*a*c) ) / (2 * a) ;

    System.out.println("x1 = " + x1);
    System.out.println("x2 = " + x2);

  }// end of main
}// end of class

平方根の計算結果をfloat 型にキャストしているのは,Math.sqrt メソッドの返り値がdouble 型であるためです。そのまま計算結果をfloat 型の変数に代入しようとすると精度の低下を警告するエラーを発してコンパイルを終了させてくれません。

このプログラムの実行結果は次の通りです。

Ketaochi.java の実行結果

x1 = -0.005001068
x2 = -79.994995

正確なx1 の値は.0.005000312539 ・・・ なので,プログラムの実行結果は3桁の有効数字しかありません。x2 の正確な値は.79.9949968 ・・・ なので,かなり正確な計算結果です。

著者プロフィール

平田敦(ひらたあつし)

地方都市の公立工業高等学校教諭。趣味はプログラミングと日本の端っこ踏破旅行。2010年のLotYはRuby。結城浩氏のような仕事をしたいと妄想する30代後半♂。

コメント

コメントの記入