今回は実数体と実数を表す BigRealField, BigReal クラスにメソッド(クロージャ型のプロパティ)を追加していきます(一覧)。 ちなみに前回に追加した FieldElement へのメソッドも使用できます(サンプルにいくつか載せてますが)。
- インスタンス生成
- メソッド使用サンプル
インスタンス生成
まずはインスタンスの生成方法。 数字リテラル、文字列リテラルから bigReal() メソッドによって対応する BigReal オブジェクトを取得できるようにしてます:
@GrabResolver('http://www5.ocn.ne.jp/~coast/repo/') @Grab('org.waman.math:wamans-math:0.0.1') WamansMath.enhance(CommonsMathPackage.UTIL) // int / Integer からの生成 def r1 = 1.bigReal() // doubel / Double からの生成 def r2 = 2.0d.bigReal() // BigDecimal からの生成 def r3 = 3.0.bigReal() // String からの生成 def r4 = '4'.bigReal() // GString からの生成 def r5 = "5".bigReal()
コンストラクタから生成するのより楽なような、変わらないような、ですけど。
メソッド使用サンプル
次はメソッドの使い方。 演算子に対応するメソッドが主です。 FieldElement に追加したメソッド (plus(), minus(), div() など。 演算子では +, -, /) も使用できます:
@GrabResolver('http://www5.ocn.ne.jp/~coast/repo/') @Grab('org.waman.math:wamans-math:0.0.1') WamansMath.enhance(CommonsMathPackage.UTIL) def r1 = 1.bigReal() def r2 = 2.bigReal() def r3 = 3.bigReal() def r_1 = -1.bigReal() // -1 (積演算の単位元 1 の和演算に関する逆元) assert BigRealField.instance.getMinusOne() == -1.bigReal() assert BigReal.MINUS_ONE == -1.bigReal() // 単位元であるかどうかの評価メソッド assert r1.isOne() assert !r2.isZero() assert r_1.isMinusOne() // 符号など assert +r2 == r2 assert -r2 == -2.bigReal() assert ~r2 == 0.5.bigReal() // ~ (bitwiseNegate()) は逆数を返すようにしてます // 1 の増減 previous() / next() assert ++r2 == 3.bigReal() assert --r2 == 2.bigReal() // 四則演算と冪乗 assert r2 + r3 == 5.bigReal() assert r2 - r3 == -1.bigReal() assert r2 * r3 == 6.bigReal() assert r3 / r2 == 1.5.bigReal() assert r2**3 == 8.bigReal() // 型変換 assert (r2 as BigDecimal) instanceof BigDecimal assert (r2 as double) instanceof Double assert (r2 as String) instanceof String // BigReal に定義されてないメソッドは bigDecimalValue() に処理を委譲 : methodMissing assert r_1.abs() == 1.bigReal()
BigReal に定義されていないけど BigDecimal に定義されているメソッド(サンプルでは最後の abs() メソッド)は、BigDecimal オブジェクトに処理を委譲した後に返り値を BigReal オブジェクトに変換するようにしてあります(ちょっと雑な実装ですけど)。
メソッドの追加スクリプト
特に詳細を気にする必要はありませんが、メソッドを追加するスクリプトはこんな感じ:
// -1 の追加 def _1 = new BigReal(-1d) BigRealField.metaClass.getMinusOne = { -> _1 } BigReal.metaClass.'static'.getMINUS_ONE = { -> _1 } // メソッド追加 (主に演算子オーバーライド) BigReal.metaClass.define{ isMinusOne = { -> delegate == _1 } negative = { -> new BigReal((BigDecimal)bigDecimalValue().negate()) } previous = { -> delegate.subtract(BigReal.ONE) } next = { -> delegate.add(BigReal.ONE) } bitwiseNegate = { -> BigReal.ONE.divide((BigReal)delegate)} power = { int n -> new BigReal((BigDecimal)bigDecimalValue().pow(n)) } // as キーワードによる型変換 asType = { Class type -> switch(type){ case BigReal.class: return delegate case BigDecimal.class: return bigDecimalValue() case double.class: return doubleValue() case Double.class: return Double.valueOf((double)doubleValue()) case String.class: return bigDecimalValue().toPlainString() } } // BigReal にないメソッドは BigReal#bigDecimalValue() で得られる BigDecimal オブジェクトへ処理を委譲 // 返り値が BigDecimal オブジェクトなら BigReal オブジェクトに変換して返す methodMissing = { String name, args -> def result = bigDecimalValue().invokeMethod(name, args) if(result instanceof BigDecimal) return new BigReal(result) else return result } } // Number オブジェクトから BigReal オブジェクトを生成 Number.metaClass.bigReal = { MathContext context = null -> switch(getClass()){ case BigDecimal.class: case BigInteger.class: return (context != null) ? new BigReal(delegate, context) : new BigReal(delegate) default: return (context != null) ? new BigReal(doubleValue(), context) : new BigReal(doubleValue()) } } // String オブジェクトから BigReal オブジェクトを生成 String.metaClass.bigReal = { MathContext context = null -> return (context != null) ? new BigReal(delegate, context) : new BigReal(delegate) }
- 作者: 奥村晴彦,杉浦方紀,津留和生,首藤一幸,土村展之
- 出版社/メーカー: 技術評論社
- 発売日: 2003/05
- メディア: 単行本
- 購入: 2人 クリック: 44回
- この商品を含むブログ (58件) を見る