読者です 読者をやめる 読者になる 読者になる

倭算数理研究所

科学・数学・学習関連の記事を、「倭マン日記」とは別に書いていくのだ!

commons-math 解読 (9) : 実数 BigReal

今回は実数を表すクラス BigReal を見ていきます。

BigReal クラスは「実数体*1の要素としての実数」の実装クラスで、前回見た FieldElement インターフェースを実装しています。 このクラスは java.math.BigDecimal クラスに FieldElement インターフェースを実装させたようなクラスであり、実装の面から言えば BigDecimal クラスのラッパ・クラスです。 まぁ、FieldElement インターフェースの一番簡単な実装例と言っていいんではないでしょうか。

BigReal クラスが FieldElement インターフェースを実装しているので、それを要素とする「体」もあり、それは BigRealField クラスで表されます。 このクラスは Field インターフェースを実装していています。 また、シングルトンとして実装されていて、BigRealField#getInstance() メソッドによってインスタンスを取得することができます。

以下では BigReal クラスに関して

  • クラス宣言
  • コンストラクタ
  • FieldElement に定義されているメソッド(四則演算等)
  • 等値評価、順序
  • 他の型への変換
  • その他のプロパティ

を順に見ていきます。

クラス宣言

BigReal クラスのクラス宣言は以下のようになってます:

package org.apache.commons.math.util;

public class BigReal implements FieldElement<BigReal>, Comparable<BigReal>, Serializable{
    ...
}

FieldElement インターフェース以外にも Comparable や Serializable なども実装してます。

コンストラクタ

まずは BigReal オブジェクトの取得方法。 BigDecimalコンストラクタには以下のようなものが定義されています:

public class BigReal{

    BigReal(BigDecimal val)

    BigReal(BigInteger val)
    BigReal(BigInteger unscaledVal, int scale)
    BigReal(BigInteger val, MathContext mc)
    BigReal(BigInteger unscaledVal, int scale, MathContext mc)

    BigReal(char[] in)
    BigReal(char[] in, int offset, int len)
    BigReal(char[] in, MathContext mc)
    BigReal(char[] in, int offset, int len, MathContext mc)

    BigReal(double val)
    BigReal(double val, MathContext mc)

    BigReal(int val)
    BigReal(int val, MathContext mc)

    BigReal(long val)
    BigReal(long val, MathContext mc)

    BigReal(String val)
    BigReal(String val, MathContext mc)

    ...
}

これらは BigDecimal に定義されているコンストラクタと同じシグニチャのようです。 まぁ BigReal が BigDecimal のラッパ・クラスなので当然かな。 MathContext クラスは「精度」や「丸め操作」の情報を持ったクラスで、それらを指定して使いたい場合は適切なオブジェクトを生成してコンストラクタに渡しましょう。 なんとなく、1つの MathContext オブジェクトに対して1つの BigRealField オブジェクトを対応させた方がいい気もしますが、BigRealField クラスはシングルトンなので無理なようです。

では、いくつかサンプルを。 Groovy では double / Double は接尾辞 "d" が必要で、接尾辞のない小数点数は BigDecimal になるのでした:

// int / Integer から
def r2 = new BigReal(2)

// double / Double から
def r3 = new BigReal(3.0d)

// BigDecimal から
def r4 = new BigReal(4.0)

// BigInteger から
def r5 = new BigReal(5G)

// String から
def r6 = new BigReal('6')

まぁ、特に問題なしかと。

FieldElement に定義されているメソッド(四則演算等)

BigReal クラスは、前回見た FieldElement インターフェースを実装しているので、BigReal オブジェクト間で四則演算を行うことができます:

public class BigReal{
    ...

    BigReal add(BigReal a)
    BigReal subtract(BigReal a)
    BigReal multiply(BigReal a)
    BigReal divide(BigReal a)

    Field<BigReal> getField()
}

サンプルはこんな感じ:

def r2 = new BigReal(2)
def r3 = new BigReal(3)

assert r2.add(r3) == new BigReal(5)
assert r2.subtract(r3) == new BigReal(-1)
assert r2.multiply(r3) == new BigReal(6)
assert r3.divide(r2) == new BigReal(1.5d)

等値評価、順序

BigReal は実数を表す値オブジェクトなので、equals メソッドは値が等しいかどうかを評価する等値評価として実装されています。 また、大小関係も評価できるように、compareTo() メソッドも実装しています(Comparable インターフェースも実装):

public class BigReal{
    ...

    boolean equals(Object other)
    int compareTo(BigReal a)
}

等値評価(equals() メソッド)は上記の四則演算の箇所にあるので省略。 順序評価は通常の不等号で評価可能(Groovy):

def r2 = new BigReal(2)
def r3 = new BigReal(3)

assert r2 < r3

他の型への変換

BigReal オブジェクトは、値として等価な BigDecimal オブジェクトや、必要なら精度を丸めた double 値を取得するためのメソッドもあります

public class BigReal{
    ...

    double doubleValue()
    BigDecimal bigDecimalValue()
}

BigReal クラス自体は Number クラスのサブクラス等ではないので(BigDecimal クラスは Number クラスのサブクラス)、double 以外の値を取得するメソッド intValue(), longValue() などは定義されていません。 サンプルは省略。

その他のプロパティ

BigReal クラスには、その他に

プロパティ名 説明 デフォルト値
scale int 割り算の際に必要なスケール(らしい) 64
roundingMode java.math.RoundingMode 丸め操作の処理方法 RoundingMode.HALF_UP

といったプロパティも定義されています。 こちらもサンプルは省略。

全体的に言って、BigReal クラスは BigDecimal クラスに FieldElement インターフェースを実装させ、メソッドを劣化させたようなクラスのよう・・・って言ったら怒られるかな(笑)

数学の基礎―集合・数・位相 (基礎数学)

数学の基礎―集合・数・位相 (基礎数学)

*1:実数体 (real number field) とは、実数 (real number) が通常の四則演算でなす「体」のことです。