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/