From: takagi@... (TAKAGI, Hiromitsu) Date: 1999-02-07T12:19:25+09:00 Subject: [ruby-dev:4802] Re: compare to NaN (Re: Re: call for finite/isnan testers) gotoken@math.sci.hokudai.ac.jp (GOTO Kentaro) writes: > > >| * Float::INFINITY の追加 > >| * Float::NaN の追加 > >| * NaN との大小判別例外 NaNCompareError クラスの追加 > >| * FLoat#infinite? の追加(Inf:正数, -Inf:負数、otherwise false) > >| * FLoat#nan? の追加(また x == Float::NaN は常に偽) > >| * FLoat#finte? の追加(Inf, -Inf or NaN:false, otherwise true) > >| * FreeBSD 環境での浮動小数点関連のトラップの抑止(main.c) > > -INFINITYを示す定数は不要か(-Float::INFINITYで十分か) > あった方がよいように思いますが名前が難しいですね。 > NEG_INFINITY かな。 > > infinite?, finite?の両方が必要か > IEEE 754 的には、これらは単に逆というわけではありません。 > 1.0 +-Inf NaN > finite? T F F > infinite? F T F > nan? F F T > 確かにどれか2つがあれば他の1つが作れますが。 > def infinite; !x.finite? && !x.nan?; end; みたく。 > > Float::infinite?は真の時に正数,負数を返す仕様は妥当か ご参考までに、Javaでの実装を紹介します。JDK1.2システムクラスのソースコー ドから、一部の抜粋です。 package java.lang; public final class Double extends Number implements Comparable { public static final double POSITIVE_INFINITY = 1.0 / 0.0; public static final double NEGATIVE_INFINITY = -1.0 / 0.0; public static final double NaN = 0.0d / 0.0; public static final double MAX_VALUE = 1.79769313486231570e+308; // public static final double MIN_VALUE = 4.94065645841246544e-324; public static final double MIN_VALUE = longBitsToDouble(1L); static public boolean isNaN(double v) { return (v != v); } static public boolean isInfinite(double v) { return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY); } public boolean isNaN() { return isNaN(value); } public boolean isInfinite() { return isInfinite(value); } public boolean equals(Object obj) { return (obj != null) && (obj instanceof Double) && (doubleToLongBits(((Double)obj).value) == doubleToLongBits(value)); } public int compareTo(Double anotherDouble) { double thisVal = value; double anotherVal = anotherDouble.value; if (thisVal < anotherVal) return -1; // Neither val is NaN, thisVal is smaller if (thisVal > anotherVal) return 1; // Neither val is NaN, thisVal is larger long thisBits = Double.doubleToLongBits(thisVal); long anotherBits = Double.doubleToLongBits(anotherVal); return (thisBits == anotherBits ? 0 : // Values are equal (thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN) 1)); // (0.0, -0.0) or (NaN, !NaN) } public int compareTo(Object o) { return compareTo((Double)o); } } 高木 浩光@電子技術総合研究所 http://www.etl.go.jp/~takagi/ (工事中)