diff options
-rw-r--r-- | complex.c | 1 | ||||
-rw-r--r-- | numeric.c | 49 | ||||
-rw-r--r-- | test/ruby/test_complex.rb | 1 | ||||
-rw-r--r-- | test/ruby/test_integer.rb | 17 | ||||
-rw-r--r-- | test/ruby/test_numeric.rb | 14 |
5 files changed, 82 insertions, 0 deletions
@@ -2335,6 +2335,7 @@ Init_Complex(void) rb_undef_method(rb_cComplex, "%"); rb_undef_method(rb_cComplex, "div"); rb_undef_method(rb_cComplex, "divmod"); + rb_undef_method(rb_cComplex, "ceildiv"); rb_undef_method(rb_cComplex, "floor"); rb_undef_method(rb_cComplex, "ceil"); rb_undef_method(rb_cComplex, "modulo"); @@ -658,6 +658,31 @@ num_div(VALUE x, VALUE y) /* * call-seq: + * ceildiv(other) -> integer + * + * Returns the quotient <tt>self/other</tt> as an integer, rounding up to the nearest integer. + * This method uses method +/+ in the derived class of +self+. + * (\Numeric itself does not define method +/+.) + * + * Of the Core and Standard Library classes, + * Float and Rational use this implementation. + * + * 3.0.ceildiv(3.0) # => 1 + * 4.0.ceildiv(3.0) # => 2 + * + * 4.0.ceildiv(-3.0) # => -1 + * -4.0.ceildiv(3.0) # => -1 + * -4.0.ceildiv(-3.0) # => 2 + */ +static VALUE +num_ceildiv(VALUE x, VALUE y) +{ + VALUE tmp = num_div(x, num_uminus(y)); + return num_uminus(tmp); +} + +/* + * call-seq: * self % other -> real_numeric * * Returns +self+ modulo +other+ as a real number. @@ -4269,6 +4294,28 @@ rb_int_idiv(VALUE x, VALUE y) return num_div(x, y); } +/* + * call-seq: + * ceildiv(other) -> integer + * + * Returns the result of division +self+ by +other+. The result is rounded up to the nearest integer. + * + * 3.ceildiv(3) # => 1 + * 4.ceildiv(3) # => 2 + * + * 4.ceildiv(-3) # => -1 + * -4.ceildiv(3) # => -1 + * -4.ceildiv(-3) # => 2 + * + * 3.ceildiv(1.2) # => 3 + */ +VALUE +rb_int_ceildiv(VALUE x, VALUE y) +{ + VALUE tmp = rb_int_idiv(x, num_uminus(y)); + return num_uminus(tmp); +} + static VALUE fix_mod(VALUE x, VALUE y) { @@ -6200,6 +6247,7 @@ Init_Numeric(void) rb_define_method(rb_cNumeric, "<=>", num_cmp, 1); rb_define_method(rb_cNumeric, "eql?", num_eql, 1); rb_define_method(rb_cNumeric, "fdiv", num_fdiv, 1); + rb_define_method(rb_cNumeric, "ceildiv", num_ceildiv, 1); rb_define_method(rb_cNumeric, "div", num_div, 1); rb_define_method(rb_cNumeric, "divmod", num_divmod, 1); rb_define_method(rb_cNumeric, "%", num_modulo, 1); @@ -6255,6 +6303,7 @@ Init_Numeric(void) rb_define_method(rb_cInteger, "remainder", int_remainder, 1); rb_define_method(rb_cInteger, "divmod", rb_int_divmod, 1); rb_define_method(rb_cInteger, "fdiv", rb_int_fdiv, 1); + rb_define_method(rb_cInteger, "ceildiv", rb_int_ceildiv, 1); rb_define_method(rb_cInteger, "**", rb_int_pow, 1); rb_define_method(rb_cInteger, "pow", rb_int_powm, -1); /* in bignum.c */ diff --git a/test/ruby/test_complex.rb b/test/ruby/test_complex.rb index a3a7546575..5cf52e812e 100644 --- a/test/ruby/test_complex.rb +++ b/test/ruby/test_complex.rb @@ -915,6 +915,7 @@ class Complex_Test < Test::Unit::TestCase assert_not_respond_to(c, :%) assert_not_respond_to(c, :div) assert_not_respond_to(c, :divmod) + assert_not_respond_to(c, :ceildiv) assert_not_respond_to(c, :floor) assert_not_respond_to(c, :ceil) assert_not_respond_to(c, :modulo) diff --git a/test/ruby/test_integer.rb b/test/ruby/test_integer.rb index a2b181c642..c3e11498be 100644 --- a/test/ruby/test_integer.rb +++ b/test/ruby/test_integer.rb @@ -704,4 +704,21 @@ class TestInteger < Test::Unit::TestCase def o.to_int; Object.new; end assert_raise_with_message(TypeError, /can't convert Object to Integer/) {Integer.try_convert(o)} end + + def test_ceildiv + assert_equal(0, 0.ceildiv(3)) + assert_equal(1, 1.ceildiv(3)) + assert_equal(1, 3.ceildiv(3)) + assert_equal(2, 4.ceildiv(3)) + + assert_equal(-1, 4.ceildiv(-3)) + assert_equal(-1, -4.ceildiv(3)) + assert_equal(2, -4.ceildiv(-3)) + + assert_equal(3, 3.ceildiv(1.2)) + assert_equal(3, 3.ceildiv(6/5r)) + + assert_equal(10, (10**100-11).ceildiv(10**99-1)) + assert_equal(11, (10**100-9).ceildiv(10**99-1)) + end end diff --git a/test/ruby/test_numeric.rb b/test/ruby/test_numeric.rb index 0593cb535d..068f9a56eb 100644 --- a/test/ruby/test_numeric.rb +++ b/test/ruby/test_numeric.rb @@ -482,4 +482,18 @@ class TestNumeric < Test::Unit::TestCase assert_equal(0, -2.pow(3, 1)) end + def test_ceildiv + assert_equal(0, 0.0.ceildiv(3.0)) + assert_equal(1, 1.0.ceildiv(3.0)) + assert_equal(1, 3.0.ceildiv(3.0)) + assert_equal(2, 4.0.ceildiv(3.0)) + + assert_equal(-1, 4.0.ceildiv(-3.0)) + assert_equal(-1, -4.0.ceildiv(3.0)) + assert_equal(2, -4.0.ceildiv(-3.0)) + + assert_equal(3, 3.0.ceildiv(1.2)) + assert_equal(3, 3.0.ceildiv(6/5r)) + assert_equal(3, (7r/2).ceildiv(6/5r)) + end end |