前田です。

In message "[ruby-list:7023] infinity"
Tadayoshi Funaba <tadf / kt.rim.or.jp> wrote:

|ボツになりそうなんで、いわないでおこうかと思ったんですが、無限大って表
|現できたら便利だと思うんですけど、どうですか。

僕も前に欲しいと思ったことがあるのですが、忘れていました(^^;

ちょっとパッチ(というほど大袈裟なものではないですが)を書いてみました。

Float::INFINITY
Float::NaN

という二つの定数と、

Float#infinite?
Float#nan?
Float#finite?

という三つのメソッドを定義しています。

-- 
前田 修吾

--- numeric.c.orig Tue Mar 10 00:49:47 1998 +++ numeric.c Tue Mar 10 01:39:36 1998 @@ -168,7 +168,7 @@ char buf[32]; sprintf(buf, "%g", RFLOAT(flt)->value); - if (strchr(buf, '.') == 0) { + if (finite(RFLOAT(flt)->value) && strchr(buf, '.') == 0) { int len = strlen(buf); char *ind = strchr(buf, 'e'); @@ -254,20 +254,12 @@ flo_div(x, y) VALUE x, y; { - INT f_y; - double d; - switch (TYPE(y)) { case T_FIXNUM: - f_y = FIX2INT(y); - if (f_y == 0) num_zerodiv(); - return float_new(RFLOAT(x)->value / (double)f_y); + return float_new(RFLOAT(x)->value / (double)FIX2INT(y)); case T_BIGNUM: - d = big2dbl(y); - if (d == 0.0) num_zerodiv(); - return float_new(RFLOAT(x)->value / d); + return float_new(RFLOAT(x)->value / big2dbl(y)); case T_FLOAT: - if (RFLOAT(y)->value == 0.0) num_zerodiv(); return float_new(RFLOAT(x)->value / RFLOAT(y)->value); default: return num_coerce_bin(x, y); @@ -443,6 +435,37 @@ } static VALUE +flo_is_infinite(flt) + VALUE flt; +{ + int ret = isinf(RFLOAT(flt)->value); + if (ret) + return INT2FIX(ret); + else + return FALSE; +} + +static VALUE +flo_is_nan(flt) + VALUE flt; +{ + if (isnan(RFLOAT(flt)->value)) + return TRUE; + else + return FALSE; +} + +static VALUE +flo_is_finite(flt) + VALUE flt; +{ + if (finite(RFLOAT(flt)->value)) + return TRUE; + else + return FALSE; +} + +static VALUE to_integer(val) VALUE val; { @@ -1145,6 +1168,8 @@ rb_define_method(cFixnum, "times", fix_dotimes, 0); cFloat = rb_define_class("Float", cNumeric); + rb_define_const(cFloat, "INFINITY", float_new(1.0 / 0.0)); + rb_define_const(cFloat, "NaN", float_new(0.0 / 0.0)); rb_undef_method(CLASS_OF(cFloat), "new"); @@ -1164,4 +1189,7 @@ rb_define_method(cFloat, "to_i", flo_to_i, 0); rb_define_method(cFloat, "to_f", flo_to_f, 0); rb_define_method(cFloat, "abs", flo_abs, 0); + rb_define_method(cFloat, "infinite?", flo_is_infinite, 0); + rb_define_method(cFloat, "nan?", flo_is_nan, 0); + rb_define_method(cFloat, "finite?", flo_is_finite, 0); }