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

ruby-changes:42490

From: nobu <ko1@a...>
Date: Wed, 13 Apr 2016 15:00:00 +0900 (JST)
Subject: [ruby-changes:42490] nobu:r54564 (trunk): numeric.c: flo_ceil

nobu	2016-04-13 15:56:36 +0900 (Wed, 13 Apr 2016)

  New Revision: 54564

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=54564

  Log:
    numeric.c: flo_ceil
    
    * numeric.c (flo_ceil): add an optional parameter, digits, as
      well as Float#round.  [Feature #12245]

  Modified files:
    trunk/ChangeLog
    trunk/numeric.c
    trunk/test/ruby/test_float.rb
Index: test/ruby/test_float.rb
===================================================================
--- test/ruby/test_float.rb	(revision 54563)
+++ test/ruby/test_float.rb	(revision 54564)
@@ -466,6 +466,27 @@ class TestFloat < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_float.rb#L466
     assert_equal(0.99, 0.998.floor(prec))
   end
 
+  def test_ceil_with_precision
+    assert_equal(1.200, 1.111.ceil(1))
+    assert_equal(1.120, 1.111.ceil(2))
+    assert_equal(11120, 11111.1.ceil(-1))
+    assert_equal(11200, 11111.1.ceil(-2))
+    assert_equal(100000, 11111.1.ceil(-5))
+
+    assert_equal(2*10**300, 1.1e300.ceil(-300))
+    assert_equal(-10**300, -1.1e300.ceil(-300))
+    assert_equal(2.0e-300, 1.1e-300.ceil(300))
+    assert_equal(-1.0e-300, -1.1e-300.ceil(300))
+
+    assert_equal(42.0, 42.0.ceil(308))
+    assert_equal(1.0e307, 1.0e307.ceil(2))
+
+    assert_raise(TypeError) {1.0.ceil("4")}
+    assert_raise(TypeError) {1.0.ceil(nil)}
+    def (prec = Object.new).to_int; 2; end
+    assert_equal(0.99, 0.981.ceil(prec))
+  end
+
   VS = [
     18446744073709551617.0,
     18446744073709551616.0,
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 54563)
+++ ChangeLog	(revision 54564)
@@ -1,4 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
-Wed Apr 13 15:54:36 2016  Nobuyoshi Nakada  <nobu@r...>
+Wed Apr 13 15:56:35 2016  Nobuyoshi Nakada  <nobu@r...>
+
+	* numeric.c (flo_ceil): add an optional parameter, digits, as
+	  well as Float#round.  [Feature #12245]
 
 	* numeric.c (flo_floor): add an optional parameter, digits, as
 	  well as Integer#floor.  [Feature #12245]
Index: numeric.c
===================================================================
--- numeric.c	(revision 54563)
+++ numeric.c	(revision 54564)
@@ -1786,21 +1786,53 @@ flo_floor(int argc, VALUE *argv, VALUE n https://github.com/ruby/ruby/blob/trunk/numeric.c#L1786
 
 /*
  *  call-seq:
- *     float.ceil  ->  integer
+ *     float.ceil([ndigits])  ->  integer or float
  *
- *  Returns the smallest Integer greater than or equal to +float+.
+ *  Returns the smallest number greater than or equal to +float+ in decimal
+ *  digits (default 0 digits).
+ *
+ *  Precision may be negative.  Returns a floating point number when +ndigits+
+ *  is positive, +self+ for zero, and ceil up for negative.
  *
  *     1.2.ceil      #=> 2
  *     2.0.ceil      #=> 2
  *     (-1.2).ceil   #=> -1
  *     (-2.0).ceil   #=> -2
+ *     1.234567.ceil(2)  #=> 1.24
+ *     1.234567.ceil(3)  #=> 1.235
+ *     1.234567.ceil(4)  #=> 1.2346
+ *     1.234567.ceil(5)  #=> 1.23457
+ *
+ *     34567.89.ceil(-5) #=> 100000
+ *     34567.89.ceil(-4) #=> 40000
+ *     34567.89.ceil(-3) #=> 35000
+ *     34567.89.ceil(-2) #=> 34600
+ *     34567.89.ceil(-1) #=> 34570
+ *     34567.89.ceil(0)  #=> 34568
+ *     34567.89.ceil(1)  #=> 34567.9
+ *     34567.89.ceil(2)  #=> 34567.89
+ *     34567.89.ceil(3)  #=> 34567.89
  */
 
 static VALUE
-flo_ceil(VALUE num)
+flo_ceil(int argc, VALUE *argv, VALUE num)
 {
-    double f = ceil(RFLOAT_VALUE(num));
-    return dbl2ival(f);
+    double number, f;
+    int ndigits = 0;
+
+    if (rb_check_arity(argc, 0, 1)) {
+       ndigits = NUM2INT(argv[0]);
+    }
+    number = RFLOAT_VALUE(num);
+    if (ndigits < 0) {
+	return rb_int_ceil(dbl2ival(ceil(number)), ndigits);
+    }
+    if (ndigits == 0) {
+	return dbl2ival(ceil(number));
+    }
+    if (float_invariant_round(number, ndigits, &num)) return num;
+    f = pow(10, ndigits);
+    return DBL2NUM(ceil(number * f) / f);
 }
 
 static int
@@ -2085,7 +2117,7 @@ num_floor(VALUE num) https://github.com/ruby/ruby/blob/trunk/numeric.c#L2117
 static VALUE
 num_ceil(VALUE num)
 {
-    return flo_ceil(rb_Float(num));
+    return flo_ceil(0, 0, rb_Float(num));
 }
 
 /*
@@ -4658,7 +4690,7 @@ Init_Numeric(void) https://github.com/ruby/ruby/blob/trunk/numeric.c#L4690
     rb_define_method(rb_cFloat, "to_i", flo_truncate, 0);
     rb_define_method(rb_cFloat, "to_int", flo_truncate, 0);
     rb_define_method(rb_cFloat, "floor", flo_floor, -1);
-    rb_define_method(rb_cFloat, "ceil", flo_ceil, 0);
+    rb_define_method(rb_cFloat, "ceil", flo_ceil, -1);
     rb_define_method(rb_cFloat, "round", flo_round, -1);
     rb_define_method(rb_cFloat, "truncate", flo_truncate, 0);
 

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

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