「機械制約」といって念頭にあるのはメモリのオーバーフローや double の精度に関する処理です。 扱うメソッドは以下の通り:
メソッド | 返り値の型 | 説明 |
---|---|---|
addAndCheck(int x, int y) addAndCheck(long a, long b) subAndCheck(int x, int y) subAndCheck(long a, long b) mulAndCheck(int x, int y) mulAndCheck(long a, long b) |
int long int long int long |
オーバーフローをチェックする演算 |
nextAfter(double d, double direction) | double | 機械が表現しうる次の数値を取得する |
equals(double x, double y) equals(double x, double y) equals(double x, double y, double eps) equals(double x, double y, int maxUlps) |
boolean | 精度を考慮したdouble の等値評価 |
compareTo(double x, double y, double eps) | int | 精度を考慮した double の順序評価 |
checkOrder(double[] val, int dir, boolean strict) | void | double の配列の順序評価 |
hash(double value) hash(double[] value) |
int | double のハッシュ計算 |
xxxAndCheck()
オーバーフローをチェックする演算には次の3つが定義されています- addAndCheck()・・・足し算
- subAndCheck()・・・引き算
- mulAndCheck()・・・かけ算
整数値の計算なので割り算はなし。 オーバーフローが起こると ArithmeticException が投げられます。
try{ // ∞+∞ MathUtils.addAndCheck(Integer.MAX_VALUE, Integer.MAX_VALUE) assert false }catch(ArithmeticException ex){} try{ // ∞-(-∞) MathUtils.subAndCheck(Integer.MAX_VALUE, Integer.MIN_VALUE) assert false }catch(ArithmeticException ex){} try{ // ∞*2 MathUtils.mulAndCheck(Integer.MAX_VALUE, 2) assert false }catch(ArithmeticException ex){}
nextAfter()
nextAfter() メソッドは機械が表現できる最も近い数字を返します。 このメソッドは java.lang.Math に定義済(1.6以降)。 完全に挙動が同じかどうかは確かめてませんが。package java.lang; public final class Math{ ... public static float nextAfter(float start, double direction) { ... } public static double nextAfter(double start, double direction) { ... } }
第2引数は大小どちらに近い数字を返すかを指定します:
- 「第1引数 < 第2引数」のとき、第1引数より小さい数字を返す
- 「第1引数 >= 第2引数」のとき、第1引数より大きい数字を返す
ちなみに、隣の数字との差は第2引数には依存しませんが、第1引数には依存します。
assert MathUtils.nextAfter(1d, 2d) == 1.0000000000000002d assert MathUtils.nextAfter(1d, 1d) == 1.0000000000000002d assert MathUtils.nextAfter(1d, 0.5d) == 0.9999999999999999d assert MathUtils.nextAfter(1d, -1d) == 0.9999999999999999d // 増加分は第1引数によって異なる assert MathUtils.nextAfter(2d, 2d) == 2.0000000000000004d // java.lang.Math#nextAfter() と同じ(だと思う) assert MathUtils.nextAfter(1d, 2d) == Math.nextAfter(1d, 2d)
equals()
equals() メソッドは double 値(もしくはその配列)の等値評価をします。 いくつかオーバーロード*1されているのでそれぞれ見ていきます。equals(double, double)
このメソッドは、double の配列の各成分を等値評価します。def array0 = [1d, 2d, 3d] as double[] def array1 = [1d, 2d, 3d] as double[] assert MathUtils.equals(array0, array1)
equals(double, double, double)
このメソッドは、第3引数で精度、つまり等しいとみなす値の範囲を指定します。 ちょっと数学っぽく書くとMathUtils.equals(x, y, e)
となっているとき「|x - y|≦ e」なら x と y は値が等しいと見なします(等しい場合も含めます inclusive)。
assert MathUtils.equals(0d, 0.01d, 0.001d) == false assert MathUtils.equals(0d, 0.01d, 0.01d) assert MathUtils.equals(0d, 0.01d, 0.1d)
equals(double, double, int)
このメソッドは、第3引数の整数で、精度が nextAfter() で返される値の何倍までを等しいと見なすかを指定します、たぶん(実際に nextAfter を呼び出してるかどうかは知りませんが)。 とりあえず、下のアサーションは通ります:def d = MathUtils.nextAfter(0d, 1d)*100 assert d == 4.94E-322 assert MathUtils.equals(0d, d, 1000) assert MathUtils.equals(0d, d, 100) assert MathUtils.equals(0d, d, 10) == false assert MathUtils.equals(0d, d, 1) == false
compareTo()
compareTo() メソッドは2つの double 値の値を精度を指定して比較します。 equals(double, double, double) と使い方は似ています。assert MathUtils.compareTo(0d, 0.01d, 0.001d) == -1 assert MathUtils.compareTo(0d, 0.01d, 0.01d) == 0 assert MathUtils.compareTo(0d, 0.01d, 0.1d) == 0
checkOrder()
配列の要素が大小順に並んでいるかどうかをチェックします。 並んでいない場合は ArithmeticException が投げられます。- 第1引数は順序を評価する double の配列
- 第2引数は小さい順(正の数)か大きい順(負の数)を指定します
- 第3引数は順序関係が狭義かどうか(値が等しい場合を許さないか許すか)です
def array = [0.0d, 1.0d, 1.0d, 1.1d] as double[] MathUtils.checkOrder(array, 1, false) // 同じ値があっても OK try{ MathUtils.checkOrder(array, 1, true) // 同じ値があるとダメ assert false }catch(IllegalArgumentException ex){}
hash()
double 値、もしくはその配列のハッシュを計算します。余談:同値関係と順序関係
以下、A を集合とする。関係
A 上の二項関係もしくは関係とは、積集合 A×A の部分集合のこと。 R を A 上の関係とし、 のときと書く。
同値関係
同値関係とは、次の条件を満たす関係のこと:
- A の任意の元 x に対して
- なら
- なら
これは Java の Object#equals() の元になってます*2。
順序関係
順序関係とは、次の条件を満たす関係のこと:
- A の任意の元 x に対して
- なら
- なら
通常、これを「≦」と書く。 これは Java の java.util.Comparator#compare() の使用の元になって(ると思い)ます。
- 作者: 齋藤正彦
- 出版社/メーカー: 東京大学出版会
- 発売日: 2002/08
- メディア: 単行本
- クリック: 21回
- この商品を含むブログ (19件) を見る
- 作者: 奥村晴彦,杉浦方紀,津留和生,首藤一幸,土村展之
- 出版社/メーカー: 技術評論社
- 発売日: 2003/05
- メディア: 単行本
- 購入: 2人 クリック: 61回
- この商品を含むブログ (61件) を見る