mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
1.4.0
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@520 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
fcd020c830
commit
65a5162550
156 changed files with 21888 additions and 18301 deletions
122
numeric.c
122
numeric.c
|
@ -6,13 +6,16 @@
|
|||
$Date$
|
||||
created at: Fri Aug 13 18:33:09 JST 1993
|
||||
|
||||
Copyright (C) 1993-1998 Yukihiro Matsumoto
|
||||
Copyright (C) 1993-1999 Yukihiro Matsumoto
|
||||
|
||||
************************************************/
|
||||
|
||||
#include "ruby.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <floatingpoint.h>
|
||||
#endif
|
||||
|
||||
static ID coerce;
|
||||
static ID to_i;
|
||||
|
@ -22,7 +25,8 @@ VALUE rb_cFloat;
|
|||
VALUE rb_cInteger;
|
||||
VALUE rb_cFixnum;
|
||||
|
||||
VALUE rb_eZeroDiv;
|
||||
VALUE rb_eZeroDivError;
|
||||
VALUE rb_eFloatDomainError;
|
||||
|
||||
ID rb_frame_last_func();
|
||||
VALUE rb_float_new();
|
||||
|
@ -31,7 +35,7 @@ double rb_big2dbl();
|
|||
void
|
||||
rb_num_zerodiv()
|
||||
{
|
||||
rb_raise(rb_eZeroDiv, "divided by 0");
|
||||
rb_raise(rb_eZeroDivError, "divided by 0");
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -163,7 +167,7 @@ num_nonzero_p(num)
|
|||
VALUE num;
|
||||
{
|
||||
if (RTEST(rb_funcall(num, rb_intern("zero?"), 0, 0))) {
|
||||
return Qfalse;
|
||||
return Qnil;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
@ -183,10 +187,19 @@ static VALUE
|
|||
flo_to_s(flt)
|
||||
VALUE flt;
|
||||
{
|
||||
char buf[32];
|
||||
char buf[24];
|
||||
char *s;
|
||||
double value = RFLOAT(flt)->value;
|
||||
|
||||
sprintf(buf, "%g", RFLOAT(flt)->value);
|
||||
if (strchr(buf, '.') == 0) {
|
||||
if (isinf(value))
|
||||
return rb_str_new2(value < 0 ? "-Infinity" : "Infinity");
|
||||
else if(isnan(value))
|
||||
return rb_str_new2("NaN");
|
||||
else
|
||||
sprintf(buf, "%-.10g", value);
|
||||
if (s = strchr(buf, ' ')) *s = '\0';
|
||||
s = buf; if (s[0] == '-') s++;
|
||||
if (strchr(s, '.') == 0) {
|
||||
int len = strlen(buf);
|
||||
char *ind = strchr(buf, 'e');
|
||||
|
||||
|
@ -274,14 +287,11 @@ flo_div(x, y)
|
|||
switch (TYPE(y)) {
|
||||
case T_FIXNUM:
|
||||
f_y = FIX2LONG(y);
|
||||
if (f_y == 0) rb_num_zerodiv();
|
||||
return rb_float_new(RFLOAT(x)->value / (double)f_y);
|
||||
case T_BIGNUM:
|
||||
d = rb_big2dbl(y);
|
||||
if (d == 0.0) rb_num_zerodiv();
|
||||
return rb_float_new(RFLOAT(x)->value / d);
|
||||
case T_FLOAT:
|
||||
if (RFLOAT(y)->value == 0.0) rb_num_zerodiv();
|
||||
return rb_float_new(RFLOAT(x)->value / RFLOAT(y)->value);
|
||||
default:
|
||||
return rb_num_coerce_bin(x, y);
|
||||
|
@ -433,7 +443,8 @@ flo_cmp(x, y)
|
|||
}
|
||||
if (a == b) return INT2FIX(0);
|
||||
if (a > b) return INT2FIX(1);
|
||||
return INT2FIX(-1);
|
||||
if (a < b) return INT2FIX(-1);
|
||||
rb_raise(rb_eFloatDomainError, "comparing NaN");
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -666,8 +677,12 @@ rb_num2long(val)
|
|||
return (long)(RFLOAT(val)->value);
|
||||
}
|
||||
else {
|
||||
rb_raise(rb_eTypeError, "float %g out of rang of integer",
|
||||
RFLOAT(val)->value);
|
||||
char buf[24];
|
||||
char *s;
|
||||
|
||||
sprintf(buf, "%-.10g", RFLOAT(val)->value);
|
||||
if (s = strchr(buf, ' ')) *s = '\0';
|
||||
rb_raise(rb_eTypeError, "float %s out of rang of integer", buf);
|
||||
}
|
||||
|
||||
case T_BIGNUM:
|
||||
|
@ -677,6 +692,11 @@ rb_num2long(val)
|
|||
rb_raise(rb_eTypeError, "no implicit conversion from string");
|
||||
return Qnil; /* not reached */
|
||||
|
||||
case T_TRUE:
|
||||
case T_FALSE:
|
||||
rb_raise(rb_eTypeError, "no implicit conversion from boolean");
|
||||
return Qnil; /* not reached */
|
||||
|
||||
default:
|
||||
val = rb_rescue(to_integer, val, fail_to_integer, val);
|
||||
if (!rb_obj_is_kind_of(val, rb_cInteger)) {
|
||||
|
@ -704,7 +724,7 @@ rb_num2int(val)
|
|||
long num = rb_num2long(val);
|
||||
|
||||
if (num < INT_MIN || INT_MAX < num) {
|
||||
rb_raise(rb_eArgError, "integer %d too big to convert to `int'.", num);
|
||||
rb_raise(rb_eArgError, "integer %d too big to convert to `int'", num);
|
||||
}
|
||||
return (int)num;
|
||||
}
|
||||
|
@ -716,7 +736,7 @@ rb_fix2int(val)
|
|||
long num = FIXNUM_P(val)?FIX2LONG(val):rb_num2long(val);
|
||||
|
||||
if (num < INT_MIN || INT_MAX < num) {
|
||||
rb_raise(rb_eArgError, "integer %d too big to convert to `int'.", num);
|
||||
rb_raise(rb_eArgError, "integer %d too big to convert to `int'", num);
|
||||
}
|
||||
return (int)num;
|
||||
}
|
||||
|
@ -777,6 +797,45 @@ int_chr(num)
|
|||
return rb_str_new(&c, 1);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_fix_induced_from(klass, x)
|
||||
VALUE klass, x;
|
||||
{
|
||||
return rb_num2fix(x);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_int_induced_from(klass, x)
|
||||
VALUE klass, x;
|
||||
{
|
||||
switch (TYPE(x)) {
|
||||
case T_FIXNUM:
|
||||
case T_BIGNUM:
|
||||
return x;
|
||||
case T_FLOAT:
|
||||
return rb_funcall(x, rb_intern("to_i"), 0);
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "failed to convert %s into Integer",
|
||||
rb_class2name(CLASS_OF(x)));
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_flo_induced_from(klass, x)
|
||||
VALUE klass, x;
|
||||
{
|
||||
switch (TYPE(x)) {
|
||||
case T_FIXNUM:
|
||||
case T_BIGNUM:
|
||||
return rb_funcall(x, rb_intern("to_f"), 0);
|
||||
case T_FLOAT:
|
||||
return x;
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "failed to convert %s into Float",
|
||||
rb_class2name(CLASS_OF(x)));
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
fix_uminus(num)
|
||||
VALUE num;
|
||||
|
@ -797,7 +856,7 @@ rb_fix2str(x, base)
|
|||
else if (base == 8) fmt[2] = 'o';
|
||||
else rb_fatal("fixnum cannot treat base %d", base);
|
||||
|
||||
sprintf(buf, fmt, FIX2LONG(x));
|
||||
snprintf(buf, 22, fmt, FIX2LONG(x));
|
||||
return rb_str_new2(buf);
|
||||
}
|
||||
|
||||
|
@ -892,7 +951,7 @@ fix_div(x, y)
|
|||
i = FIX2LONG(y);
|
||||
if (i == 0) rb_num_zerodiv();
|
||||
i = FIX2LONG(x)/i;
|
||||
return INT2FIX(i);
|
||||
return INT2NUM(i); /* FIXNUM_MIN / -1 > FIXNUM_MAX */
|
||||
}
|
||||
return rb_num_coerce_bin(x, y);
|
||||
}
|
||||
|
@ -940,15 +999,13 @@ fix_pow(x, y)
|
|||
|
||||
b = FIX2LONG(y);
|
||||
if (b == 0) return INT2FIX(1);
|
||||
if (b == 1) return x;
|
||||
a = FIX2LONG(x);
|
||||
if (b > 0) {
|
||||
return rb_big_pow(rb_int2big(a), y);
|
||||
}
|
||||
return rb_float_new(pow((double)a, (double)b));
|
||||
}
|
||||
else if (NIL_P(y)) {
|
||||
return INT2FIX(1);
|
||||
}
|
||||
return rb_num_coerce_bin(x, y);
|
||||
}
|
||||
|
||||
|
@ -1044,7 +1101,7 @@ static VALUE
|
|||
fix_rev(num)
|
||||
VALUE num;
|
||||
{
|
||||
unsigned long val = FIX2ULONG(num);
|
||||
long val = FIX2LONG(num);
|
||||
|
||||
val = ~val;
|
||||
return rb_int2inum(val);
|
||||
|
@ -1309,20 +1366,23 @@ fix_step(from, to, step)
|
|||
if (!FIXNUM_P(to) || !FIXNUM_P(step))
|
||||
return int_step(from, to, step);
|
||||
|
||||
i = FIX2LONG(from);
|
||||
end = FIX2LONG(to);
|
||||
diff = FIX2LONG(step);
|
||||
|
||||
if (diff == 0) {
|
||||
rb_raise(rb_eArgError, "step cannot be 0");
|
||||
}
|
||||
else if (diff > 0) {
|
||||
for (i=FIX2LONG(from); i <= end; i+=diff) {
|
||||
if (diff > 0) {
|
||||
while (i <= end) {
|
||||
rb_yield(INT2FIX(i));
|
||||
i += diff;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i=FIX2LONG(from); i >= end; i+=diff) {
|
||||
while (i >= end) {
|
||||
rb_yield(INT2FIX(i));
|
||||
i += diff;
|
||||
}
|
||||
}
|
||||
return from;
|
||||
|
@ -1354,10 +1414,15 @@ fix_zero_p(num)
|
|||
void
|
||||
Init_Numeric()
|
||||
{
|
||||
#ifdef __FreeBSD__
|
||||
/* allow divide by zero -- Inf */
|
||||
fpsetmask(fpgetmask() & ~(FP_X_DZ|FP_X_INV|FP_X_OFL));
|
||||
#endif
|
||||
coerce = rb_intern("coerce");
|
||||
to_i = rb_intern("to_i");
|
||||
|
||||
rb_eZeroDiv = rb_define_class("ZeroDivisionError", rb_eStandardError);
|
||||
rb_eZeroDivError = rb_define_class("ZeroDivisionError", rb_eStandardError);
|
||||
rb_eFloatDomainError = rb_define_class("FloatDomainError", rb_eStandardError);
|
||||
rb_cNumeric = rb_define_class("Numeric", rb_cObject);
|
||||
|
||||
rb_include_module(rb_cNumeric, rb_mComparable);
|
||||
|
@ -1380,11 +1445,15 @@ Init_Numeric()
|
|||
rb_define_method(rb_cInteger, "downto", int_downto, 1);
|
||||
rb_define_method(rb_cInteger, "step", int_step, 2);
|
||||
rb_define_method(rb_cInteger, "times", int_dotimes, 0);
|
||||
rb_include_module(rb_cInteger, rb_mPrecision);
|
||||
rb_define_method(rb_cInteger, "succ", int_succ, 0);
|
||||
rb_define_method(rb_cInteger, "next", int_succ, 0);
|
||||
rb_define_method(rb_cInteger, "chr", int_chr, 0);
|
||||
|
||||
rb_cFixnum = rb_define_class("Fixnum", rb_cInteger);
|
||||
rb_include_module(rb_cFixnum, rb_mPrecision);
|
||||
rb_define_singleton_method(rb_cFixnum, "induced_from", rb_fix_induced_from, 1);
|
||||
rb_define_singleton_method(rb_cInteger, "induced_from", rb_int_induced_from, 1);
|
||||
|
||||
rb_undef_method(CLASS_OF(rb_cFixnum), "new");
|
||||
|
||||
|
@ -1437,6 +1506,9 @@ Init_Numeric()
|
|||
|
||||
rb_undef_method(CLASS_OF(rb_cFloat), "new");
|
||||
|
||||
rb_define_singleton_method(rb_cFloat, "induced_from", rb_flo_induced_from, 1);
|
||||
rb_include_module(rb_cFloat, rb_mPrecision);
|
||||
|
||||
rb_define_method(rb_cFloat, "to_s", flo_to_s, 0);
|
||||
rb_define_method(rb_cFloat, "coerce", flo_coerce, 1);
|
||||
rb_define_method(rb_cFloat, "-@", flo_uminus, 0);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue