From: Tadashi Saito Date: 2003-08-04T23:08:09+09:00 Subject: [ruby-dev:21133] [BigDecimal] Comparable again 斎藤です。 Comparable由来の各メソッドの仕様を修正するパッチです。 新たにexportされたrb_num_coerce_relopを用いた物を、改めて流します。 よろしくお願いします。 # まつもとさん、配慮ありがとうございました。 Index: bigdecimal.c =================================================================== RCS file: /src/ruby/ext/bigdecimal/bigdecimal.c,v retrieving revision 1.18 diff -u -p -r1.18 bigdecimal.c --- bigdecimal.c 1 Aug 2003 04:48:32 -0000 1.18 +++ bigdecimal.c 3 Aug 2003 07:34:08 -0000 @@ -58,7 +58,6 @@ VALUE rb_cBigDecimal; /* * ================== Ruby Interface part ========================== */ -static ID coerce; /* * **** BigDecimal version **** @@ -79,44 +78,6 @@ static int VpInternalRound(Real *c,int i /* * **** BigDecimal part **** */ -/* Following functions borrowed from numeric.c */ -static VALUE -coerce_body(VALUE *x) -{ - return rb_funcall(x[1], coerce, 1, x[0]); -} - -static VALUE -coerce_rescue(VALUE *x) -{ - rb_raise(rb_eTypeError, "%s can't be coerced into %s", - rb_special_const_p(x[1])? - rb_str2cstr(rb_inspect(x[1]),0): - rb_class2name(CLASS_OF(x[1])), - rb_class2name(CLASS_OF(x[0]))); - return (VALUE)0; -} - -static void -do_coerce(VALUE *x, VALUE *y) -{ - VALUE ary; - VALUE a[2]; - a[0] = *x; a[1] = *y; - ary = rb_rescue(coerce_body, (VALUE)a, coerce_rescue, (VALUE)a); - if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) { - rb_raise(rb_eTypeError, "coerce must return [x, y]"); - } - *x = RARRAY(ary)->ptr[0]; - *y = RARRAY(ary)->ptr[1]; -} - -static VALUE -DoSomeOne(VALUE x, VALUE y) -{ - do_coerce(&x, &y); - return rb_funcall(x, rb_frame_last_func(), 1, y); -} static void BigDecimal_delete(Real *pv) @@ -177,8 +138,8 @@ SomeOneMayDoIt: if(must) { rb_raise(rb_eTypeError, "%s can't be coerced into BigDecimal", rb_special_const_p(v)? - rb_str2cstr(rb_inspect(v),0): - rb_class2name(CLASS_OF(v)) + RSTRING(rb_inspect(v))->ptr: + rb_obj_classname(v) ); } return NULL; /* NULL means to coerce */ @@ -490,7 +451,7 @@ BigDecimal_add(VALUE self, VALUE r) GUARD_OBJ(a,GetVpValue(self,1)); b = GetVpValue(r,0); - if(!b) return DoSomeOne(self,r); + if(!b) return rb_num_coerce_bin(self,r); SAVE(b); if(VpIsNaN(b)) return b->obj; @@ -519,7 +480,7 @@ BigDecimal_sub(VALUE self, VALUE r) GUARD_OBJ(a,GetVpValue(self,1)); b = GetVpValue(r,0); - if(!b) return DoSomeOne(self,r); + if(!b) return rb_num_coerce_bin(self,r); SAVE(b); if(VpIsNaN(b)) return b->obj; @@ -540,18 +501,6 @@ BigDecimal_sub(VALUE self, VALUE r) return ToValue(c); } -static S_INT -BigDecimalCmp(VALUE self, VALUE r) -{ - ENTER(5); - Real *a, *b; - GUARD_OBJ(a,GetVpValue(self,1)); - b = GetVpValue(r,0); - if(!b) return DoSomeOne(self,r); - SAVE(b); - return VpComp(a, b); -} - static VALUE BigDecimal_zero(VALUE self) { @@ -570,8 +519,14 @@ static VALUE BigDecimal_comp(VALUE self, VALUE r) { S_INT e; - e = BigDecimalCmp(self, r); - if(e==999) return rb_float_new(VpGetDoubleNaN()); + ENTER(5); + Real *a, *b; + GUARD_OBJ(a,GetVpValue(self,1)); + b = GetVpValue(r,0); + if(!b) return rb_num_coerce_cmp(self,r); + SAVE(b); + e = VpComp(a, b); + if(e==999) return Qnil; return INT2FIX(e); } @@ -582,7 +537,7 @@ BigDecimal_eq(VALUE self, VALUE r) Real *a, *b; GUARD_OBJ(a,GetVpValue(self,1)); b = GetVpValue(r,0); - if(!b) return Qfalse; /* Not comparable */ + if(!b) return Qnil; /* Not comparable */ SAVE(b); return VpComp(a, b)? Qfalse:Qtrue; } @@ -603,7 +558,12 @@ static VALUE BigDecimal_lt(VALUE self, VALUE r) { S_INT e; - e = BigDecimalCmp(self, r); + ENTER(1); + Real *a, *b; + GUARD_OBJ(a,GetVpValue(self,1)); + b = GetVpValue(r,0); + if(!b) return rb_num_coerce_relop(self, r); + e = VpComp(a, b); if(e==999) return Qfalse; return(e < 0) ? Qtrue : Qfalse; } @@ -612,7 +572,12 @@ static VALUE BigDecimal_le(VALUE self, VALUE r) { S_INT e; - e = BigDecimalCmp(self, r); + ENTER(1); + Real *a, *b; + GUARD_OBJ(a,GetVpValue(self,1)); + b = GetVpValue(r,0); + if(!b) return rb_num_coerce_relop(self, r); + e = VpComp(a, b); if(e==999) return Qfalse; return(e <= 0) ? Qtrue : Qfalse; } @@ -621,7 +586,12 @@ static VALUE BigDecimal_gt(VALUE self, VALUE r) { S_INT e; - e = BigDecimalCmp(self, r); + ENTER(1); + Real *a, *b; + GUARD_OBJ(a,GetVpValue(self,1)); + b = GetVpValue(r,0); + if(!b) return rb_num_coerce_relop(self, r); + e = VpComp(a, b); if(e==999) return Qfalse; return(e > 0) ? Qtrue : Qfalse; } @@ -630,7 +600,12 @@ static VALUE BigDecimal_ge(VALUE self, VALUE r) { S_INT e; - e = BigDecimalCmp(self, r); + ENTER(1); + Real *a, *b; + GUARD_OBJ(a,GetVpValue(self,1)); + b = GetVpValue(r,0); + if(!b) return rb_num_coerce_relop(self, r); + e = VpComp(a, b); if(e==999) return Qfalse; return(e >= 0) ? Qtrue : Qfalse; } @@ -655,7 +630,7 @@ BigDecimal_mult(VALUE self, VALUE r) GUARD_OBJ(a,GetVpValue(self,1)); b = GetVpValue(r,0); - if(!b) return DoSomeOne(self,r); + if(!b) return rb_num_coerce_bin(self,r); SAVE(b); mx = a->Prec + b->Prec; @@ -674,7 +649,7 @@ BigDecimal_divide(Real **c, Real **res, GUARD_OBJ(a,GetVpValue(self,1)); b = GetVpValue(r,0); - if(!b) return DoSomeOne(self,r); + if(!b) return rb_num_coerce_bin(self,r); SAVE(b); *div = b; mx =(a->MaxPrec + b->MaxPrec + 1) * VpBaseFig(); @@ -718,7 +693,7 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, GUARD_OBJ(a,GetVpValue(self,1)); b = GetVpValue(r,0); - if(!b) return DoSomeOne(self,r); + if(!b) return rb_num_coerce_bin(self,r); SAVE(b); if(VpIsNaN(a) || VpIsNaN(b)) goto NaN; @@ -785,7 +760,7 @@ BigDecimal_divremain(VALUE self, VALUE r GUARD_OBJ(a,GetVpValue(self,1)); b = GetVpValue(r,0); - if(!b) return DoSomeOne(self,r); + if(!b) return rb_num_coerce_bin(self,r); SAVE(b); mx =(a->MaxPrec + b->MaxPrec) *VpBaseFig(); @@ -1303,7 +1278,6 @@ Init_bigdecimal(void) { /* Initialize VP routines */ VpInit((U_LONG)0); - coerce = rb_intern("coerce"); /* Class and method registration */ rb_cBigDecimal = rb_define_class("BigDecimal",rb_cNumeric); -- 斎藤ただし