[前][次][番号順一覧][スレッド一覧]

ruby-changes:14719

From: mame <ko1@a...>
Date: Fri, 5 Feb 2010 00:36:49 +0900 (JST)
Subject: [ruby-changes:14719] Ruby:r26574 (trunk): * bignum.c (big_gt, big_ge, big_lt, big_ge): added Bignum#>, >=, < and

mame	2010-02-05 00:36:29 +0900 (Fri, 05 Feb 2010)

  New Revision: 26574

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=26574

  Log:
    * bignum.c (big_gt, big_ge, big_lt, big_ge): added Bignum#>, >=, < and
      <= to allow to compare with BigDecimal.  [ruby-dev:40167]

  Modified files:
    trunk/ChangeLog
    trunk/bignum.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 26573)
+++ ChangeLog	(revision 26574)
@@ -1,3 +1,8 @@
+Fri Feb  5 00:34:24 2010  Yusuke Endoh  <mame@t...>
+
+	* bignum.c (big_gt, big_ge, big_lt, big_ge): added Bignum#>, >=, < and
+	  <= to allow to compare with BigDecimal.  [ruby-dev:40167]
+
 Thu Feb  4 15:47:27 2010  NARUSE, Yui  <naruse@r...>
 
 	* thread_pthread.c (native_thread_init_stack): use get_stack.
Index: bignum.c
===================================================================
--- bignum.c	(revision 26573)
+++ bignum.c	(revision 26574)
@@ -1329,7 +1329,114 @@
 	    (RBIGNUM_SIGN(x) ? INT2FIX(-1) : INT2FIX(1));
 }
 
+static VALUE
+big_op(VALUE x, VALUE y, int op)
+{
+    long xlen = RBIGNUM_LEN(x);
+    BDIGIT *xds, *yds;
+    VALUE rel;
+    int n;
+
+    switch (TYPE(y)) {
+      case T_FIXNUM:
+      case T_BIGNUM:
+	rel = rb_big_cmp(x, y);
+	break;
+
+      case T_FLOAT:
+	{
+	    double a = RFLOAT_VALUE(y);
+
+	    if (isinf(a)) {
+		if (a > 0.0) return INT2FIX(-1);
+		else return INT2FIX(1);
+	    }
+	    rel = rb_dbl_cmp(rb_big2dbl(x), a);
+	    break;
+	}
+
+      default:
+	{
+	    ID id = 0;
+	    switch (op) {
+		case 0: id = '>'; break;
+		case 1: id = rb_intern(">="); break;
+		case 2: id = '<'; break;
+		case 3: id = rb_intern("<="); break;
+	    }
+	    return rb_num_coerce_relop(x, y, id);
+	}
+    }
+
+    if (NIL_P(rel)) return Qfalse;
+    n = FIX2INT(rel);
+
+    switch (op) {
+	case 0: return n >  0 ? Qtrue : Qfalse;
+	case 1: return n >= 0 ? Qtrue : Qfalse;
+	case 2: return n <  0 ? Qtrue : Qfalse;
+	case 3: return n <= 0 ? Qtrue : Qfalse;
+    }
+    return Qundef;
+}
+
 /*
+ * call-seq:
+ *   big > real  ->  true or false
+ *
+ * Returns <code>true</code> if the value of <code>big</code> is
+ * greater than that of <code>real</code>.
+ */
+
+static VALUE
+big_gt(VALUE x, VALUE y)
+{
+    return big_op(x, y, 0);
+}
+
+/*
+ * call-seq:
+ *   big >= real  ->  true or false
+ *
+ * Returns <code>true</code> if the value of <code>big</code> is
+ * greater than or equal to that of <code>real</code>.
+ */
+
+static VALUE
+big_ge(VALUE x, VALUE y)
+{
+    return big_op(x, y, 1);
+}
+
+/*
+ * call-seq:
+ *   big < real  ->  true or false
+ *
+ * Returns <code>true</code> if the value of <code>big</code> is
+ * less than that of <code>real</code>.
+ */
+
+static VALUE
+big_lt(VALUE x, VALUE y)
+{
+    return big_op(x, y, 2);
+}
+
+/*
+ * call-seq:
+ *   big <= real  ->  true or false
+ *
+ * Returns <code>true</code> if the value of <code>big</code> is
+ * less than or equal to that of <code>real</code>.
+ */
+
+static VALUE
+big_le(VALUE x, VALUE y)
+{
+    return big_op(x, y, 3);
+}
+
+/*
  *  call-seq:
  *     big == obj  => true or false
  *
@@ -3286,6 +3393,10 @@
 
     rb_define_method(rb_cBignum, "<=>", rb_big_cmp, 1);
     rb_define_method(rb_cBignum, "==", rb_big_eq, 1);
+    rb_define_method(rb_cBignum, ">", big_gt, 1);
+    rb_define_method(rb_cBignum, ">=", big_ge, 1);
+    rb_define_method(rb_cBignum, "<", big_lt, 1);
+    rb_define_method(rb_cBignum, "<=", big_le, 1);
     rb_define_method(rb_cBignum, "===", rb_big_eq, 1);
     rb_define_method(rb_cBignum, "eql?", rb_big_eql, 1);
     rb_define_method(rb_cBignum, "hash", rb_big_hash, 0);

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]