summaryrefslogtreecommitdiff
path: root/test/ruby/test_integer.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby/test_integer.rb')
-rw-r--r--test/ruby/test_integer.rb1240
1 files changed, 682 insertions, 558 deletions
diff --git a/test/ruby/test_integer.rb b/test/ruby/test_integer.rb
index cfda9e5985..f9bf4fa20c 100644
--- a/test/ruby/test_integer.rb
+++ b/test/ruby/test_integer.rb
@@ -1,160 +1,47 @@
+# frozen_string_literal: false
require 'test/unit'
class TestInteger < Test::Unit::TestCase
- VS = [
- -0x1000000000000000000000000000000000000000000000002,
- -0x1000000000000000000000000000000000000000000000001,
- -0x1000000000000000000000000000000000000000000000000,
- -0xffffffffffffffffffffffffffffffffffffffffffffffff,
- -0x1000000000000000000000002,
- -0x1000000000000000000000001,
- -0x1000000000000000000000000,
- -0xffffffffffffffffffffffff,
- -0x10000000000000002,
- -0x10000000000000001,
- -0x10000000000000000,
- -0xffffffffffffffff,
- -0x4000000000000002,
- -0x4000000000000001,
- -0x4000000000000000,
- -0x3fffffffffffffff,
- -0x100000002,
- -0x100000001,
- -0x100000000,
- -0xffffffff,
- -0xc717a08d, # 0xc717a08d * 0x524b2245 = 0x4000000000000001
- -0x80000002,
- -0x80000001,
- -0x80000000,
- -0x7fffffff,
- -0x524b2245,
- -0x40000002,
- -0x40000001,
- -0x40000000,
- -0x3fffffff,
- -0x10002,
- -0x10001,
- -0x10000,
- -0xffff,
- -0x8101, # 0x8101 * 0x7f01 = 0x40000001
- -0x8002,
- -0x8001,
- -0x8000,
- -0x7fff,
- -0x7f01,
- -65,
- -64,
- -63,
- -62,
- -33,
- -32,
- -31,
- -30,
- -3,
- -2,
- -1,
- 0,
- 1,
- 2,
- 3,
- 30,
- 31,
- 32,
- 33,
- 62,
- 63,
- 64,
- 65,
- 0x7f01,
- 0x7ffe,
- 0x7fff,
- 0x8000,
- 0x8001,
- 0x8101,
- 0xfffe,
- 0xffff,
- 0x10000,
- 0x10001,
- 0x3ffffffe,
- 0x3fffffff,
- 0x40000000,
- 0x40000001,
- 0x524b2245,
- 0x7ffffffe,
- 0x7fffffff,
- 0x80000000,
- 0x80000001,
- 0xc717a08d,
- 0xfffffffe,
- 0xffffffff,
- 0x100000000,
- 0x100000001,
- 0x3ffffffffffffffe,
- 0x3fffffffffffffff,
- 0x4000000000000000,
- 0x4000000000000001,
- 0xfffffffffffffffe,
- 0xffffffffffffffff,
- 0x10000000000000000,
- 0x10000000000000001,
- 0xffffffffffffffffffffffff,
- 0x1000000000000000000000000,
- 0x1000000000000000000000001,
- 0xffffffffffffffffffffffffffffffffffffffffffffffff,
- 0x1000000000000000000000000000000000000000000000000,
- 0x1000000000000000000000000000000000000000000000001
- ]
-
- #VS.map! {|v| 0x4000000000000000.coerce(v)[0] }
-
- BDSIZE = 0x4000000000000000.coerce(0)[0].size
- def self.bdsize(x)
- ((x + 1) / 8 + BDSIZE) / BDSIZE * BDSIZE
- end
- def bdsize(x)
- self.class.bdsize(x)
- end
-
- min = -1
- min *= 2 while min.class == Fixnum
- FIXNUM_MIN = min/2
- max = 1
- max *= 2 while (max-1).class == Fixnum
- FIXNUM_MAX = max/2-1
-
- def test_fixnum_range
- assert_instance_of(Bignum, FIXNUM_MIN-1)
- assert_instance_of(Fixnum, FIXNUM_MIN)
- assert_instance_of(Fixnum, FIXNUM_MAX)
- assert_instance_of(Bignum, FIXNUM_MAX+1)
- end
-
- def check_class(n)
- if FIXNUM_MIN <= n && n <= FIXNUM_MAX
- assert_instance_of(Fixnum, n)
- else
- assert_instance_of(Bignum, n)
- end
- end
+ FIXNUM_MIN = RbConfig::LIMITS['FIXNUM_MIN']
+ FIXNUM_MAX = RbConfig::LIMITS['FIXNUM_MAX']
+ LONG_MAX = RbConfig::LIMITS['LONG_MAX']
def test_aref
- VS.each {|a|
- 100.times {|i|
- assert_equal((a >> i).odd? ? 1 : 0, a[i], "(#{a})[#{i}]")
- }
- }
- VS.each {|a|
- VS.each {|b|
- c = nil
- assert_nothing_raised("(#{a})[#{b}]") { c = a[b] }
- check_class(c)
- if b < 0
- assert_equal(0, c, "(#{a})[#{b}]")
+
+ [
+ *-16..16,
+ *(FIXNUM_MIN-2)..(FIXNUM_MIN+2),
+ *(FIXNUM_MAX-2)..(FIXNUM_MAX+2),
+ ].each do |n|
+ (-64..64).each do |idx|
+ assert_equal((n >> idx) & 1, n[idx])
+ end
+ [*-66..-62, *-34..-30, *-5..5, *30..34, *62..66].each do |idx|
+ (0..100).each do |len|
+ assert_equal((n >> idx) & ((1 << len) - 1), n[idx, len], "#{ n }[#{ idx }, #{ len }]")
+ end
+ (0..100).each do |len|
+ assert_equal((n >> idx) & ((1 << (len + 1)) - 1), n[idx..idx+len], "#{ n }[#{ idx }..#{ idx+len }]")
+ assert_equal((n >> idx) & ((1 << len) - 1), n[idx...idx+len], "#{ n }[#{ idx }...#{ idx+len }]")
+ end
+
+ # endless
+ assert_equal((n >> idx), n[idx..], "#{ n }[#{ idx }..]")
+ assert_equal((n >> idx), n[idx...], "#{ n }[#{ idx }...#]")
+
+ # beginless
+ if idx >= 0 && n & ((1 << (idx + 1)) - 1) != 0
+ assert_raise(ArgumentError, "#{ n }[..#{ idx }]") { n[..idx] }
else
- assert_equal((a >> b).odd? ? 1 : 0, c, "(#{a})[#{b}]")
+ assert_equal(0, n[..idx], "#{ n }[..#{ idx }]")
end
- }
- }
+ if idx >= 0 && n & ((1 << idx) - 1) != 0
+ assert_raise(ArgumentError, "#{ n }[...#{ idx }]") { n[...idx] }
+ else
+ assert_equal(0, n[...idx], "#{ n }[...#{ idx }]")
+ end
+ end
+ end
# assert_equal(1, (1 << 0x40000000)[0x40000000], "[ruby-dev:31271]")
# assert_equal(0, (-1 << 0x40000001)[0x40000000], "[ruby-dev:31271]")
@@ -163,491 +50,728 @@ class TestInteger < Test::Unit::TestCase
assert_equal(1, 0x400000001[big_zero], "[ruby-dev:31271]")
end
- def test_plus
- VS.each {|a|
- VS.each {|b|
- c = a + b
- check_class(c)
- assert_equal(b + a, c, "#{a} + #{b}")
- assert_equal(a, c - b, "(#{a} + #{b}) - #{b}")
- assert_equal(a-~b-1, c, "#{a} + #{b}") # Hacker's Delight
- assert_equal((a^b)+2*(a&b), c, "#{a} + #{b}") # Hacker's Delight
- assert_equal((a|b)+(a&b), c, "#{a} + #{b}") # Hacker's Delight
- assert_equal(2*(a|b)-(a^b), c, "#{a} + #{b}") # Hacker's Delight
- }
- }
+ def test_pow
+ assert_not_equal(0, begin
+ 0**-1
+ rescue
+ nil
+ end, "[ruby-dev:32084] [ruby-dev:34547]")
+
+ assert_raise(ArgumentError) {2 ** -0x4000000000000000}
+
+ <<~EXPRS.each_line.with_index(__LINE__+1) do |expr, line|
+ crash01: 111r+11**-11111161111111
+ crash02: 1118111111111**-1111111111111111**1+1==11111
+ crash03: -1111111**-1111*11 - -11** -1111111
+ crash04: 1118111111111** -1111111111111111**1+11111111111**1 ===111
+ crash05: 11** -111155555555555555 -55 !=5-555
+ crash07: 1 + 111111111**-1111811111
+ crash08: 18111111111**-1111111111111111**1 + 1111111111**-1111**1
+ crash10: -7 - -1111111** -1111**11
+ crash12: 1118111111111** -1111111111111111**1 + 1111 - -1111111** -1111*111111111119
+ crash13: 1.0i - -11** -1111111
+ crash14: 11111**111111111**111111 * -11111111111111111111**-111111111111
+ crash15: ~1**1111 + -~1**~1**111
+ crash17: 11** -1111111**1111 /11i
+ crash18: 5555i**-5155 - -9111111**-1111**11
+ crash19: 111111*-11111111111111111111**-1111111111111111
+ crash20: 1111**111-11**-11111**11
+ crash21: 11**-10111111119-1i -1r
+ EXPRS
+ name, expr = expr.split(':', 2)
+ assert_ruby_status(%w"-W0", "begin; #{ expr }; rescue ArgumentError; end", name)
+ end
end
- def test_minus
- VS.each {|a|
- VS.each {|b|
- c = a - b
- check_class(c)
- assert_equal(a, c + b, "(#{a} - #{b}) + #{b}")
- assert_equal(-b, c - a, "(#{a} - #{b}) - #{a}")
- assert_equal(a+~b+1, c, "#{a} - #{b}") # Hacker's Delight
- assert_equal((a^b)-2*(b&~a), c, "#{a} - #{b}") # Hacker's Delight
- assert_equal((a&~b)-(b&~a), c, "#{a} - #{b}") # Hacker's Delight
- assert_equal(2*(a&~b)-(a^b), c, "#{a} - #{b}") # Hacker's Delight
- }
- }
- end
+ def test_lshift
+ assert_equal(0, 1 << -0x40000000)
+ assert_equal(0, 1 << -0x40000001)
+ assert_equal(0, 1 << -0x80000000)
+ assert_equal(0, 1 << -0x80000001)
- def test_mult
- VS.each {|a|
- VS.each {|b|
- c = a * b
- check_class(c)
- assert_equal(b * a, c, "#{a} * #{b}")
- assert_equal(b, c / a, "(#{a} * #{b}) / #{a}") if a != 0
- assert_equal(a.abs * b.abs, (a * b).abs, "(#{a} * #{b}).abs")
- assert_equal((a-100)*(b-100)+(a-100)*100+(b-100)*100+10000, c, "#{a} * #{b}")
- assert_equal((a+100)*(b+100)-(a+100)*100-(b+100)*100+10000, c, "#{a} * #{b}")
- }
+ char_bit = RbConfig::LIMITS["UCHAR_MAX"].bit_length
+ size_max = RbConfig::LIMITS["SIZE_MAX"]
+ size_bit_max = size_max * char_bit
+ assert_raise_with_message(RangeError, /shift width/) {
+ 1 << size_bit_max
}
end
- def test_divmod
- VS.each {|a|
- VS.each {|b|
- if b == 0
- assert_raise(ZeroDivisionError) { a.divmod(b) }
- else
- q, r = a.divmod(b)
- check_class(q)
- check_class(r)
- assert_equal(a, b*q+r)
- assert(r.abs < b.abs)
- assert(0 < b ? (0 <= r && r < b) : (b < r && r <= 0))
- assert_equal(q, a/b)
- assert_equal(q, a.div(b))
- assert_equal(r, a%b)
- assert_equal(r, a.modulo(b))
- end
- }
- }
+ def test_rshift
+ assert_predicate((1 >> 0x80000000), :zero?)
+ assert_predicate((1 >> 0xffffffff), :zero?)
+ assert_predicate((1 >> 0x100000000), :zero?)
+ # assert_equal((1 << 0x40000000), (1 >> -0x40000000))
+ # assert_equal((1 << 0x40000001), (1 >> -0x40000001))
end
- def test_pow
- small_values = VS.find_all {|v| 0 <= v && v < 1000 }
- VS.each {|a|
- small_values.each {|b|
- c = a ** b
- check_class(c)
- d = 1
- b.times { d *= a }
- assert_equal(d, c, "(#{a}) ** #{b}")
- if a != 0
- d = c
- b.times { d /= a }
- assert_equal(1, d, "((#{a}) ** #{b}) / #{a} / ...(#{b} times)...")
- end
- }
+ def test_Integer
+ assert_raise(ArgumentError) {Integer("0x-1")}
+ assert_raise(ArgumentError) {Integer("-0x-1")}
+ assert_raise(ArgumentError) {Integer("0x 123")}
+ assert_raise(ArgumentError) {Integer("0x 123")}
+ assert_raise(ArgumentError) {Integer("0x0x5")}
+ assert_raise(ArgumentError) {Integer("0x0x000000005")}
+ assert_nothing_raised(ArgumentError) {
+ assert_equal(1540841, "0x0x5".to_i(36))
+ }
+ assert_raise(ArgumentError) { Integer("--0") }
+ assert_raise(ArgumentError) { Integer("-+0") }
+ assert_raise(ArgumentError) { Integer("++1") }
+ assert_raise(ArgumentError) { Integer("") }
+ assert_raise(ArgumentError) { Integer("10 x") }
+ assert_raise(ArgumentError) { Integer("1__2") }
+ assert_raise(ArgumentError) { Integer("1z") }
+ assert_raise(ArgumentError) { Integer("46116860184273__87904") }
+ assert_raise(ArgumentError) { Integer("4611686018427387904_") }
+ assert_raise(ArgumentError) { Integer("4611686018427387904 :") }
+ assert_equal(0x4000000000000000, Integer("46_11_686_0184273_87904"))
+ assert_raise(ArgumentError) { Integer("\0") }
+ assert_nothing_raised(ArgumentError, "[ruby-core:13873]") {
+ assert_equal(0, Integer("0 "))
}
+ assert_nothing_raised(ArgumentError, "[ruby-core:14139]") {
+ assert_equal(0377, Integer("0_3_7_7"))
+ }
+ assert_raise(ArgumentError, "[ruby-core:14139]") {Integer("0__3_7_7")}
+ assert_equal(1234, Integer(1234))
+ assert_equal(1, Integer(1.234))
+
+ assert_equal(2 ** 50, Integer(2.0 ** 50))
+ assert_raise(TypeError) { Integer(nil) }
+
+ bug14552 = '[ruby-core:85813]'
+ obj = Object.new
+ def obj.to_int; "str"; end
+ assert_raise(TypeError, bug14552) { Integer(obj) }
+ def obj.to_i; 42; end
+ assert_equal(42, Integer(obj), bug14552)
+
+ obj = Object.new
+ def obj.to_i; "str"; end
+ assert_raise(TypeError) { Integer(obj) }
+
+ bug6192 = '[ruby-core:43566]'
+ assert_raise(Encoding::CompatibilityError, bug6192) {Integer("0".encode("utf-16be"))}
+ assert_raise(Encoding::CompatibilityError, bug6192) {Integer("0".encode("utf-16le"))}
+ assert_raise(Encoding::CompatibilityError, bug6192) {Integer("0".encode("utf-32be"))}
+ assert_raise(Encoding::CompatibilityError, bug6192) {Integer("0".encode("utf-32le"))}
+ assert_raise(Encoding::CompatibilityError, bug6192) {Integer("0".encode("iso-2022-jp"))}
+
+ EnvUtil.with_default_internal(Encoding::UTF_8) do
+ assert_raise_with_message(ArgumentError, /\u{1f4a1}/) {Integer("\u{1f4a1}")}
+ end
- assert_equal(0**-1 == 0, false)
+ obj = Struct.new(:s).new(%w[42 not-an-integer])
+ def obj.to_str; s.shift; end
+ assert_equal(42, Integer(obj, 10))
+
+ assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
+ begin;
+ class Float
+ undef to_int
+ def to_int; raise "conversion failed"; end
+ end
+ assert_equal (1 << 100), Integer((1 << 100).to_f)
+ assert_equal 1, Integer(1.0)
+ end;
end
- def test_not
- VS.each {|a|
- b = ~a
- check_class(b)
- assert_equal(-1 ^ a, b, "~#{a}")
- assert_equal(-a-1, b, "~#{a}") # Hacker's Delight
- assert_equal(0, a & b, "#{a} & ~#{a}")
- assert_equal(-1, a | b, "#{a} | ~#{a}")
+ def test_Integer_with_invalid_exception
+ assert_raise(ArgumentError) {
+ Integer("0", exception: 1)
}
end
- def test_or
- VS.each {|a|
- VS.each {|b|
- c = a | b
- check_class(c)
- assert_equal(b | a, c, "#{a} | #{b}")
- assert_equal(a + b - (a&b), c, "#{a} | #{b}")
- assert_equal((a & ~b) + b, c, "#{a} | #{b}") # Hacker's Delight
- assert_equal(-1, c | ~a, "(#{a} | #{b}) | ~#{a})")
- }
+ def test_Integer_with_exception_keyword
+ assert_nothing_raised(ArgumentError) {
+ assert_equal(nil, Integer("1z", exception: false))
+ }
+ assert_nothing_raised(ArgumentError) {
+ assert_equal(nil, Integer(Object.new, exception: false))
+ }
+ assert_nothing_raised(ArgumentError) {
+ o = Object.new
+ def o.to_i; 42.5; end
+ assert_equal(nil, Integer(o, exception: false))
+ }
+ assert_nothing_raised(ArgumentError) {
+ o = Object.new
+ def o.to_i; raise; end
+ assert_equal(nil, Integer(o, exception: false))
+ }
+ assert_nothing_raised(ArgumentError) {
+ o = Object.new
+ def o.to_int; raise; end
+ assert_equal(nil, Integer(o, exception: false))
+ }
+ assert_nothing_raised(FloatDomainError) {
+ assert_equal(nil, Integer(Float::INFINITY, exception: false))
+ }
+ assert_nothing_raised(FloatDomainError) {
+ assert_equal(nil, Integer(-Float::INFINITY, exception: false))
+ }
+ assert_nothing_raised(FloatDomainError) {
+ assert_equal(nil, Integer(Float::NAN, exception: false))
}
- end
- def test_and
- VS.each {|a|
- VS.each {|b|
- c = a & b
- check_class(c)
- assert_equal(b & a, c, "#{a} & #{b}")
- assert_equal(a + b - (a|b), c, "#{a} & #{b}")
- assert_equal((~a | b) - ~a, c, "#{a} & #{b}") # Hacker's Delight
- assert_equal(0, c & ~a, "(#{a} & #{b}) & ~#{a}")
- }
+ assert_raise(ArgumentError) {
+ Integer("1z", exception: true)
+ }
+ assert_raise(TypeError) {
+ Integer(nil, exception: true)
}
+ assert_nothing_raised(TypeError) {
+ assert_equal(nil, Integer(nil, exception: false))
+ }
+
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class Integer;def method_missing(*);"";end;end
+ assert_equal(0, Integer("0", 2))
+ end;
end
- def test_xor
- VS.each {|a|
- VS.each {|b|
- c = a ^ b
- check_class(c)
- assert_equal(b ^ a, c, "#{a} ^ #{b}")
- assert_equal((a|b)-(a&b), c, "#{a} ^ #{b}") # Hacker's Delight
- assert_equal(b, c ^ a, "(#{a} ^ #{b}) ^ #{a}")
- }
- }
+ def test_Integer_when_to_str
+ def (obj = Object.new).to_str
+ "0x10"
+ end
+ assert_equal(16, Integer(obj))
end
- def test_lshift
- small_values = VS.find_all {|v| v < 8000 }
- VS.each {|a|
- small_values.each {|b|
- c = a << b
- check_class(c)
- if 0 <= b
- assert_equal(a, c >> b, "(#{a} << #{b}) >> #{b}")
- assert_equal(a * 2**b, c, "#{a} << #{b}")
- end
- 0.upto(c.size*8+10) {|nth|
- assert_equal(a[nth-b], c[nth], "(#{a} << #{b})[#{nth}]")
- }
- }
- }
- assert_equal(0, 1 << -0x40000000)
- assert_equal(0, 1 << -0x40000001)
- assert_equal(0, 1 << -0x80000000)
- assert_equal(0, 1 << -0x80000001)
- # assert_equal(bdsize(0x80000000), (1 << 0x80000000).size)
+ def test_Integer_with_base
+ assert_equal(1234, Integer("1234", 10))
+ assert_equal(668, Integer("1234", 8))
+ assert_equal(4660, Integer("1234", 16))
+ assert_equal(49360, Integer("1234", 36))
+ # decimal, not octal
+ assert_equal(1234, Integer("01234", 10))
+ assert_raise(ArgumentError) { Integer("0x123", 10) }
+ assert_raise(ArgumentError) { Integer(1234, 10) }
+ assert_raise(ArgumentError) { Integer(12.34, 10) }
+ assert_raise(ArgumentError) { Integer(Object.new, 1) }
+
+ assert_raise(ArgumentError) { Integer(1, 1, 1) }
+
+ def (base = Object.new).to_int
+ 8
+ end
+ assert_equal(8, Integer("10", base))
+
+ assert_raise(TypeError) { Integer("10", "8") }
+ def (base = Object.new).to_int
+ "8"
+ end
+ assert_raise(TypeError) { Integer("10", base) }
end
- def test_rshift
- small_values = VS.find_all {|v| -8000 < v }
- VS.each {|a|
- small_values.each {|b|
- c = a >> b
- check_class(c)
- if b <= 0
- assert_equal(a, c << b, "(#{a} >> #{b}) << #{b}")
- assert_equal(a * 2**(-b), c, "#{a} >> #{b}")
- end
- 0.upto(c.size*8+10) {|nth|
- assert_equal(a[nth+b], c[nth], "(#{a} >> #{b})[#{nth}]")
- }
- }
- }
- # assert_equal(bdsize(0x40000001), (1 >> -0x40000001).size)
- assert((1 >> 0x80000000).zero?)
- assert((1 >> 0xffffffff).zero?)
- assert((1 >> 0x100000000).zero?)
- # assert_equal((1 << 0x40000000), (1 >> -0x40000000))
- # assert_equal((1 << 0x40000001), (1 >> -0x40000001))
+ def test_int_p
+ assert_not_predicate(1.0, :integer?)
+ assert_predicate(1, :integer?)
end
def test_succ
- VS.each {|a|
- b = a.succ
- check_class(b)
- assert_equal(a+1, b, "(#{a}).succ")
- assert_equal(a, b.pred, "(#{a}).succ.pred")
- assert_equal(a, b-1, "(#{a}).succ - 1")
- }
+ assert_equal(2, 1.send(:succ))
end
- def test_pred
- VS.each {|a|
- b = a.pred
- check_class(b)
- assert_equal(a-1, b, "(#{a}).pred")
- assert_equal(a, b.succ, "(#{a}).pred.succ")
- assert_equal(a, b + 1, "(#{a}).pred + 1")
- }
+ def test_chr
+ assert_equal("a", "a".ord.chr)
+ assert_raise(RangeError) { (-1).chr }
+ assert_raise(RangeError) { 0x100.chr }
+ assert_raise_with_message(RangeError, "3000000000 out of char range") { 3_000_000_000.chr }
end
- def test_unary_plus
- VS.each {|a|
- b = +a
- check_class(b)
- assert_equal(a, b, "+(#{a})")
- }
- end
+ def test_upto
+ a = []
+ assert_equal(1, 1.upto(3) {|x| a << x })
+ assert_equal([1, 2, 3], a)
- def test_unary_minus
- VS.each {|a|
- b = -a
- check_class(b)
- assert_equal(0-a, b, "-(#{a})")
- assert_equal(~a+1, b, "-(#{a})")
- assert_equal(0, a+b, "#{a}+(-(#{a}))")
- }
+ a = []
+ assert_equal(1, 1.upto(0) {|x| a << x })
+ assert_equal([], a)
+
+ y = 2**30 - 1
+ a = []
+ assert_equal(y, y.upto(y+2) {|x| a << x })
+ assert_equal([y, y+1, y+2], a)
end
- def test_cmp
- VS.each_with_index {|a, i|
- VS.each_with_index {|b, j|
- assert_equal(i <=> j, a <=> b, "#{a} <=> #{b}")
- assert_equal(i < j, a < b, "#{a} < #{b}")
- assert_equal(i <= j, a <= b, "#{a} <= #{b}")
- assert_equal(i > j, a > b, "#{a} > #{b}")
- assert_equal(i >= j, a >= b, "#{a} >= #{b}")
- }
- }
+ def test_downto
+ a = []
+ assert_equal(-1, -1.downto(-3) {|x| a << x })
+ assert_equal([-1, -2, -3], a)
+
+ a = []
+ assert_equal(1, 1.downto(2) {|x| a << x })
+ assert_equal([], a)
+
+ y = -(2**30)
+ a = []
+ assert_equal(y, y.downto(y-2) {|x| a << x })
+ assert_equal([y, y-1, y-2], a)
end
- def test_eq
- VS.each_with_index {|a, i|
- VS.each_with_index {|b, j|
- c = a == b
- assert_equal(b == a, c, "#{a} == #{b}")
- assert_equal(i == j, c, "#{a} == #{b}")
- }
- }
+ def test_times
+ (2**32).times do |i|
+ break if i == 2
+ end
end
- def test_abs
- VS.each {|a|
- b = a.abs
- check_class(b)
- if a < 0
- assert_equal(-a, b, "(#{a}).abs")
- else
- assert_equal(a, b, "(#{a}).abs")
+ def test_times_bignum_redefine_plus_lt
+ assert_separately([], "#{<<-"begin;"}\n#{<<~"end;"}")
+ begin;
+ called = false
+ Integer.class_eval do
+ alias old_succ succ
+ undef succ
+ define_method(:succ){|x| called = true; x+1}
+ alias old_lt <
+ undef <
+ define_method(:<){|x| called = true}
end
- }
+
+ fix = 1
+ fix.times{break 0}
+ fix_called = called
+
+ called = false
+
+ big = 2**65
+ big.times{break 0}
+ big_called = called
+
+ Integer.class_eval do
+ undef succ
+ alias succ old_succ
+ undef <
+ alias < old_lt
+ end
+
+ # Asssert that Fixnum and Bignum behave consistently
+ bug18377 = "[ruby-core:106361]"
+ assert_equal(fix_called, big_called, bug18377)
+ end;
end
- def test_ceil
- VS.each {|a|
- b = a.ceil
- check_class(b)
- assert_equal(a, b, "(#{a}).ceil")
- }
+ def assert_int_equal(expected, result, mesg = nil)
+ assert_kind_of(Integer, result, mesg)
+ assert_equal(expected, result, mesg)
end
- def test_floor
- VS.each {|a|
- b = a.floor
- check_class(b)
- assert_equal(a, b, "(#{a}).floor")
- }
+ def assert_float_equal(expected, result, mesg = nil)
+ assert_kind_of(Float, result, mesg)
+ assert_equal(expected, result, mesg)
end
def test_round
- VS.each {|a|
- b = a.round
- check_class(b)
- assert_equal(a, b, "(#{a}).round")
- }
+ assert_int_equal(11111, 11111.round)
+ assert_int_equal(11111, 11111.round(0))
+
+ assert_int_equal(11111, 11111.round(1))
+ assert_int_equal(11111, 11111.round(2))
+
+ assert_int_equal(11110, 11111.round(-1))
+ assert_int_equal(11100, 11111.round(-2))
+ assert_int_equal(+200, +249.round(-2))
+ assert_int_equal(+300, +250.round(-2))
+ assert_int_equal(-200, -249.round(-2))
+ assert_int_equal(+200, +249.round(-2, half: :even))
+ assert_int_equal(+200, +250.round(-2, half: :even))
+ assert_int_equal(+300, +349.round(-2, half: :even))
+ assert_int_equal(+400, +350.round(-2, half: :even))
+ assert_int_equal(+200, +249.round(-2, half: :up))
+ assert_int_equal(+300, +250.round(-2, half: :up))
+ assert_int_equal(+300, +349.round(-2, half: :up))
+ assert_int_equal(+400, +350.round(-2, half: :up))
+ assert_int_equal(+200, +249.round(-2, half: :down))
+ assert_int_equal(+200, +250.round(-2, half: :down))
+ assert_int_equal(+300, +349.round(-2, half: :down))
+ assert_int_equal(+300, +350.round(-2, half: :down))
+ assert_int_equal(-300, -250.round(-2))
+ assert_int_equal(-200, -249.round(-2, half: :even))
+ assert_int_equal(-200, -250.round(-2, half: :even))
+ assert_int_equal(-300, -349.round(-2, half: :even))
+ assert_int_equal(-400, -350.round(-2, half: :even))
+ assert_int_equal(-200, -249.round(-2, half: :up))
+ assert_int_equal(-300, -250.round(-2, half: :up))
+ assert_int_equal(-300, -349.round(-2, half: :up))
+ assert_int_equal(-400, -350.round(-2, half: :up))
+ assert_int_equal(-200, -249.round(-2, half: :down))
+ assert_int_equal(-200, -250.round(-2, half: :down))
+ assert_int_equal(-300, -349.round(-2, half: :down))
+ assert_int_equal(-300, -350.round(-2, half: :down))
+ assert_int_equal(+30 * 10**70, (+25 * 10**70).round(-71))
+ assert_int_equal(-30 * 10**70, (-25 * 10**70).round(-71))
+ assert_int_equal(+20 * 10**70, (+25 * 10**70 - 1).round(-71))
+ assert_int_equal(-20 * 10**70, (-25 * 10**70 + 1).round(-71))
+ assert_int_equal(+40 * 10**70, (+35 * 10**70).round(-71))
+ assert_int_equal(-40 * 10**70, (-35 * 10**70).round(-71))
+ assert_int_equal(+30 * 10**70, (+35 * 10**70 - 1).round(-71))
+ assert_int_equal(-30 * 10**70, (-35 * 10**70 + 1).round(-71))
+ assert_int_equal(+20 * 10**70, (+25 * 10**70).round(-71, half: :even))
+ assert_int_equal(-20 * 10**70, (-25 * 10**70).round(-71, half: :even))
+ assert_int_equal(+20 * 10**70, (+25 * 10**70 - 1).round(-71, half: :even))
+ assert_int_equal(-20 * 10**70, (-25 * 10**70 + 1).round(-71, half: :even))
+ assert_int_equal(+40 * 10**70, (+35 * 10**70).round(-71, half: :even))
+ assert_int_equal(-40 * 10**70, (-35 * 10**70).round(-71, half: :even))
+ assert_int_equal(+30 * 10**70, (+35 * 10**70 - 1).round(-71, half: :even))
+ assert_int_equal(-30 * 10**70, (-35 * 10**70 + 1).round(-71, half: :even))
+ assert_int_equal(+30 * 10**70, (+25 * 10**70).round(-71, half: :up))
+ assert_int_equal(-30 * 10**70, (-25 * 10**70).round(-71, half: :up))
+ assert_int_equal(+20 * 10**70, (+25 * 10**70 - 1).round(-71, half: :up))
+ assert_int_equal(-20 * 10**70, (-25 * 10**70 + 1).round(-71, half: :up))
+ assert_int_equal(+40 * 10**70, (+35 * 10**70).round(-71, half: :up))
+ assert_int_equal(-40 * 10**70, (-35 * 10**70).round(-71, half: :up))
+ assert_int_equal(+30 * 10**70, (+35 * 10**70 - 1).round(-71, half: :up))
+ assert_int_equal(-30 * 10**70, (-35 * 10**70 + 1).round(-71, half: :up))
+ assert_int_equal(+20 * 10**70, (+25 * 10**70).round(-71, half: :down))
+ assert_int_equal(-20 * 10**70, (-25 * 10**70).round(-71, half: :down))
+ assert_int_equal(+20 * 10**70, (+25 * 10**70 - 1).round(-71, half: :down))
+ assert_int_equal(-20 * 10**70, (-25 * 10**70 + 1).round(-71, half: :down))
+ assert_int_equal(+30 * 10**70, (+35 * 10**70).round(-71, half: :down))
+ assert_int_equal(-30 * 10**70, (-35 * 10**70).round(-71, half: :down))
+ assert_int_equal(+30 * 10**70, (+35 * 10**70 - 1).round(-71, half: :down))
+ assert_int_equal(-30 * 10**70, (-35 * 10**70 + 1).round(-71, half: :down))
+
+ assert_int_equal(1111_1111_1111_1111_1111_1111_1111_1110, 1111_1111_1111_1111_1111_1111_1111_1111.round(-1))
+ assert_int_equal(-1111_1111_1111_1111_1111_1111_1111_1110, (-1111_1111_1111_1111_1111_1111_1111_1111).round(-1))
+
+ assert_int_equal(1111_1111_1111_1111_1111_1111_1111_1111, 1111_1111_1111_1111_1111_1111_1111_1111.round(1))
+ assert_int_equal(10**400, (10**400).round(1))
end
- def test_truncate
- VS.each {|a|
- b = a.truncate
- check_class(b)
- assert_equal(a, b, "(#{a}).truncate")
- }
+ def test_floor
+ assert_int_equal(11111, 11111.floor)
+ assert_int_equal(11111, 11111.floor(0))
+
+ assert_int_equal(11111, 11111.floor(1))
+ assert_int_equal(11111, 11111.floor(2))
+
+ assert_int_equal(11110, 11110.floor(-1))
+ assert_int_equal(11110, 11119.floor(-1))
+ assert_int_equal(11100, 11100.floor(-2))
+ assert_int_equal(11100, 11199.floor(-2))
+ assert_int_equal(0, 11111.floor(-5))
+ assert_int_equal(+200, +299.floor(-2))
+ assert_int_equal(+300, +300.floor(-2))
+ assert_int_equal(-300, -299.floor(-2))
+ assert_int_equal(-300, -300.floor(-2))
+ assert_int_equal(+20 * 10**70, (+25 * 10**70).floor(-71))
+ assert_int_equal(-30 * 10**70, (-25 * 10**70).floor(-71))
+ assert_int_equal(+20 * 10**70, (+25 * 10**70 - 1).floor(-71))
+ assert_int_equal(-30 * 10**70, (-25 * 10**70 + 1).floor(-71))
+
+ assert_int_equal(1111_1111_1111_1111_1111_1111_1111_1110, 1111_1111_1111_1111_1111_1111_1111_1111.floor(-1))
+ assert_int_equal(-1111_1111_1111_1111_1111_1111_1111_1120, (-1111_1111_1111_1111_1111_1111_1111_1111).floor(-1))
+
+ assert_int_equal(1111_1111_1111_1111_1111_1111_1111_1111, 1111_1111_1111_1111_1111_1111_1111_1111.floor(1))
+ assert_int_equal(10**400, (10**400).floor(1))
+
+ assert_int_equal(-10000000000, -1.floor(-10), "[Bug #20654]")
+ assert_int_equal(-100000000000000000000, -1.floor(-20), "[Bug #20654]")
+ assert_int_equal(-100000000000000000000000000000000000000000000000000, -1.floor(-50), "[Bug #20654]")
end
- def test_remainder
- VS.each {|a|
- VS.each {|b|
- if b == 0
- assert_raise(ZeroDivisionError) { a.divmod(b) }
- else
- r = a.remainder(b)
- check_class(r)
- if a < 0
- assert_operator(-b.abs, :<, r, "#{a}.remainder(#{b})")
- assert_operator(0, :>=, r, "#{a}.remainder(#{b})")
- elsif 0 < a
- assert_operator(0, :<=, r, "#{a}.remainder(#{b})")
- assert_operator(b.abs, :>, r, "#{a}.remainder(#{b})")
- else
- assert_equal(0, r, "#{a}.remainder(#{b})")
- end
- end
- }
- }
+ def test_ceil
+ assert_int_equal(11111, 11111.ceil)
+ assert_int_equal(11111, 11111.ceil(0))
+
+ assert_int_equal(11111, 11111.ceil(1))
+ assert_int_equal(11111, 11111.ceil(2))
+
+ assert_int_equal(11110, 11110.ceil(-1))
+ assert_int_equal(11120, 11119.ceil(-1))
+ assert_int_equal(11200, 11101.ceil(-2))
+ assert_int_equal(11200, 11200.ceil(-2))
+ assert_int_equal(100000, 11111.ceil(-5))
+ assert_int_equal(300, 299.ceil(-2))
+ assert_int_equal(300, 300.ceil(-2))
+ assert_int_equal(-200, -299.ceil(-2))
+ assert_int_equal(-300, -300.ceil(-2))
+ assert_int_equal(+30 * 10**70, (+25 * 10**70).ceil(-71))
+ assert_int_equal(-20 * 10**70, (-25 * 10**70).ceil(-71))
+ assert_int_equal(+30 * 10**70, (+25 * 10**70 - 1).ceil(-71))
+ assert_int_equal(-20 * 10**70, (-25 * 10**70 + 1).ceil(-71))
+
+ assert_int_equal(1111_1111_1111_1111_1111_1111_1111_1120, 1111_1111_1111_1111_1111_1111_1111_1111.ceil(-1))
+ assert_int_equal(-1111_1111_1111_1111_1111_1111_1111_1110, (-1111_1111_1111_1111_1111_1111_1111_1111).ceil(-1))
+
+ assert_int_equal(1111_1111_1111_1111_1111_1111_1111_1111, 1111_1111_1111_1111_1111_1111_1111_1111.ceil(1))
+ assert_int_equal(10**400, (10**400).ceil(1))
+
+ assert_int_equal(10000000000, 1.ceil(-10), "[Bug #20654]")
+ assert_int_equal(100000000000000000000, 1.ceil(-20), "[Bug #20654]")
+ assert_int_equal(100000000000000000000000000000000000000000000000000, 1.ceil(-50), "[Bug #20654]")
end
- def test_zero_nonzero
- VS.each {|a|
- z = a.zero?
- n = a.nonzero?
- if a == 0
- assert_equal(true, z, "(#{a}).zero?")
- assert_equal(nil, n, "(#{a}).nonzero?")
- else
- assert_equal(false, z, "(#{a}).zero?")
- assert_equal(a, n, "(#{a}).nonzero?")
- check_class(n)
- end
- assert(z ^ n, "(#{a}).zero? ^ (#{a}).nonzero?")
- }
+ def test_truncate
+ assert_int_equal(11111, 11111.truncate)
+ assert_int_equal(11111, 11111.truncate(0))
+
+ assert_int_equal(11111, 11111.truncate(1))
+ assert_int_equal(11111, 11111.truncate(2))
+
+ assert_int_equal(11110, 11110.truncate(-1))
+ assert_int_equal(11110, 11119.truncate(-1))
+ assert_int_equal(11100, 11100.truncate(-2))
+ assert_int_equal(11100, 11199.truncate(-2))
+ assert_int_equal(0, 11111.truncate(-5))
+ assert_int_equal(+200, +299.truncate(-2))
+ assert_int_equal(+300, +300.truncate(-2))
+ assert_int_equal(-200, -299.truncate(-2))
+ assert_int_equal(-300, -300.truncate(-2))
+ assert_int_equal(+20 * 10**70, (+25 * 10**70).truncate(-71))
+ assert_int_equal(-20 * 10**70, (-25 * 10**70).truncate(-71))
+ assert_int_equal(+20 * 10**70, (+25 * 10**70 - 1).truncate(-71))
+ assert_int_equal(-20 * 10**70, (-25 * 10**70 + 1).truncate(-71))
+
+ assert_int_equal(1111_1111_1111_1111_1111_1111_1111_1110, 1111_1111_1111_1111_1111_1111_1111_1111.truncate(-1))
+ assert_int_equal(-1111_1111_1111_1111_1111_1111_1111_1110, (-1111_1111_1111_1111_1111_1111_1111_1111).truncate(-1))
+
+ assert_int_equal(1111_1111_1111_1111_1111_1111_1111_1111, 1111_1111_1111_1111_1111_1111_1111_1111.truncate(1))
+ assert_int_equal(10**400, (10**400).truncate(1))
+ end
+
+ MimicInteger = Struct.new(:to_int)
+ module CoercionToInt
+ def coerce(other)
+ [other, to_int]
+ end
end
- def test_even_odd
- VS.each {|a|
- e = a.even?
- o = a.odd?
- assert_equal((a % 2) == 0, e, "(#{a}).even?")
- assert_equal((a % 2) == 1, o, "(#{a}).odd")
- assert_equal((a & 1) == 0, e, "(#{a}).even?")
- assert_equal((a & 1) == 1, o, "(#{a}).odd")
- assert(e ^ o, "(#{a}).even? ^ (#{a}).odd?")
- }
+ def test_bitwise_and_with_integer_mimic_object
+ obj = MimicInteger.new(10)
+ assert_raise(TypeError, '[ruby-core:39491]') { 3 & obj }
+ obj.extend(CoercionToInt)
+ assert_equal(3 & 10, 3 & obj)
end
- def test_to_s
- 2.upto(36) {|radix|
- VS.each {|a|
- s = a.to_s(radix)
- b = s.to_i(radix)
- assert_equal(a, b, "(#{a}).to_s(#{radix}).to_i(#{radix})")
- }
- }
+ def test_bitwise_or_with_integer_mimic_object
+ obj = MimicInteger.new(10)
+ assert_raise(TypeError, '[ruby-core:39491]') { 3 | obj }
+ obj.extend(CoercionToInt)
+ assert_equal(3 | 10, 3 | obj)
end
- def test_printf_x
- VS.reverse_each {|a|
- s = sprintf("%x", a)
- if /\A\.\./ =~ s
- b = -($'.tr('0123456789abcdef', 'fedcba9876543210').to_i(16) + 1)
- else
- b = s.to_i(16)
- end
- assert_equal(a, b, "sprintf('%x', #{a}) = #{s.inspect}")
- }
+ def test_bitwise_xor_with_integer_mimic_object
+ obj = MimicInteger.new(10)
+ assert_raise(TypeError, '[ruby-core:39491]') { 3 ^ obj }
+ obj.extend(CoercionToInt)
+ assert_equal(3 ^ 10, 3 ^ obj)
end
- def test_printf_x_sign
- VS.reverse_each {|a|
- s = sprintf("%+x", a)
- b = s.to_i(16)
- assert_equal(a, b, "sprintf('%+x', #{a}) = #{s.inspect}")
- s = sprintf("% x", a)
- b = s.to_i(16)
- assert_equal(a, b, "sprintf('% x', #{a}) = #{s.inspect}")
- }
+ module CoercionToSelf
+ def coerce(other)
+ [self.class.new(other), self]
+ end
end
- def test_printf_o
- VS.reverse_each {|a|
- s = sprintf("%o", a)
- if /\A\.\./ =~ s
- b = -($'.tr('01234567', '76543210').to_i(8) + 1)
- else
- b = s.to_i(8)
+ def test_bitwise_and_with_integer_coercion
+ obj = Struct.new(:value) do
+ include(CoercionToSelf)
+ def &(other)
+ self.value & other.value
end
- assert_equal(a, b, "sprintf('%o', #{a}) = #{s.inspect}")
- }
+ end.new(10)
+ assert_equal(3 & 10, 3 & obj)
end
- def test_printf_o_sign
- VS.reverse_each {|a|
- s = sprintf("%+o", a)
- b = s.to_i(8)
- assert_equal(a, b, "sprintf('%+o', #{a}) = #{s.inspect}")
- s = sprintf("% o", a)
- b = s.to_i(8)
- assert_equal(a, b, "sprintf('% o', #{a}) = #{s.inspect}")
- }
+ def test_bitwise_or_with_integer_coercion
+ obj = Struct.new(:value) do
+ include(CoercionToSelf)
+ def |(other)
+ self.value | other.value
+ end
+ end.new(10)
+ assert_equal(3 | 10, 3 | obj)
end
- def test_printf_b
- VS.reverse_each {|a|
- s = sprintf("%b", a)
- if /\A\.\./ =~ s
- b = -($'.tr('01', '10').to_i(2) + 1)
+ def test_bitwise_xor_with_integer_coercion
+ obj = Struct.new(:value) do
+ include(CoercionToSelf)
+ def ^(other)
+ self.value ^ other.value
+ end
+ end.new(10)
+ assert_equal(3 ^ 10, 3 ^ obj)
+ end
+
+ def test_bit_length
+ assert_equal(13, (-2**12-1).bit_length)
+ assert_equal(12, (-2**12).bit_length)
+ assert_equal(12, (-2**12+1).bit_length)
+ assert_equal(9, -0x101.bit_length)
+ assert_equal(8, -0x100.bit_length)
+ assert_equal(8, -0xff.bit_length)
+ assert_equal(1, -2.bit_length)
+ assert_equal(0, -1.bit_length)
+ assert_equal(0, 0.bit_length)
+ assert_equal(1, 1.bit_length)
+ assert_equal(8, 0xff.bit_length)
+ assert_equal(9, 0x100.bit_length)
+ assert_equal(9, 0x101.bit_length)
+ assert_equal(12, (2**12-1).bit_length)
+ assert_equal(13, (2**12).bit_length)
+ assert_equal(13, (2**12+1).bit_length)
+
+ assert_equal(10001, (-2**10000-1).bit_length)
+ assert_equal(10000, (-2**10000).bit_length)
+ assert_equal(10000, (-2**10000+1).bit_length)
+ assert_equal(10000, (2**10000-1).bit_length)
+ assert_equal(10001, (2**10000).bit_length)
+ assert_equal(10001, (2**10000+1).bit_length)
+
+ 2.upto(1000) {|i|
+ n = 2**i
+ assert_equal(i+1, (-n-1).bit_length, "(#{-n-1}).bit_length")
+ assert_equal(i, (-n).bit_length, "(#{-n}).bit_length")
+ assert_equal(i, (-n+1).bit_length, "(#{-n+1}).bit_length")
+ assert_equal(i, (n-1).bit_length, "#{n-1}.bit_length")
+ assert_equal(i+1, (n).bit_length, "#{n}.bit_length")
+ assert_equal(i+1, (n+1).bit_length, "#{n+1}.bit_length")
+ }
+ end
+
+ def test_digits
+ assert_equal([0], 0.digits)
+ assert_equal([1], 1.digits)
+ assert_equal([0, 9, 8, 7, 6, 5, 4, 3, 2, 1], 1234567890.digits)
+ assert_equal([90, 78, 56, 34, 12], 1234567890.digits(100))
+ assert_equal([10, 5, 6, 8, 0, 10, 8, 6, 1], 1234567890.digits(13))
+ assert_equal((2 ** 1024).to_s(7).chars.map(&:to_i).reverse, (2 ** 1024).digits(7))
+ assert_equal([0] * 100 + [1], (2 ** (128 * 100)).digits(2 ** 128))
+ end
+
+ def test_digits_for_negative_numbers
+ assert_raise(Math::DomainError) { -1.digits }
+ assert_raise(Math::DomainError) { -1234567890.digits }
+ assert_raise(Math::DomainError) { -1234567890.digits(100) }
+ assert_raise(Math::DomainError) { -1234567890.digits(13) }
+ end
+
+ def test_digits_for_invalid_base_numbers
+ assert_raise(ArgumentError) { 10.digits(-1) }
+ assert_raise(ArgumentError) { 10.digits(0) }
+ assert_raise(ArgumentError) { 10.digits(1) }
+ end
+
+ def test_digits_for_non_integral_base_numbers
+ assert_equal([1], 1.digits(10r))
+ assert_equal([1], 1.digits(10.0))
+ assert_raise(RangeError) { 10.digits(10+1i) }
+ end
+
+ def test_digits_for_non_numeric_base_argument
+ assert_raise(TypeError) { 10.digits("10") }
+ assert_raise(TypeError) { 10.digits("a") }
+
+ class << (o = Object.new)
+ def to_int
+ 10
+ end
+ end
+ assert_equal([0, 1], 10.digits(o))
+ end
+
+ def test_square_root
+ assert_raise(TypeError) {Integer.sqrt("x")}
+ assert_raise(Math::DomainError) {Integer.sqrt(-1)}
+ assert_equal(0, Integer.sqrt(0))
+ (1...4).each {|i| assert_equal(1, Integer.sqrt(i))}
+ (4...9).each {|i| assert_equal(2, Integer.sqrt(i))}
+ (9...16).each {|i| assert_equal(3, Integer.sqrt(i))}
+ (1..40).each do |i|
+ mesg = "10**#{i}"
+ s = Integer.sqrt(n = 10**i)
+ if i.even?
+ assert_equal(10**(i/2), Integer.sqrt(n), mesg)
else
- b = s.to_i(2)
+ assert_include((s**2)...(s+1)**2, n, mesg)
end
- assert_equal(a, b, "sprintf('%b', #{a}) = #{s.inspect}")
- }
- end
+ end
+ 50.step(400, 10) do |i|
+ exact = 10**(i/2)
+ x = 10**i
+ assert_equal(exact, Integer.sqrt(x), "10**#{i}")
+ assert_equal(exact, Integer.sqrt(x+1), "10**#{i}+1")
+ assert_equal(exact-1, Integer.sqrt(x-1), "10**#{i}-1")
+ end
- def test_printf_b_sign
- VS.reverse_each {|a|
- s = sprintf("%+b", a)
- b = s.to_i(2)
- assert_equal(a, b, "sprintf('%+b', #{a}) = #{s.inspect}")
- s = sprintf("% b", a)
- b = s.to_i(2)
- assert_equal(a, b, "sprintf('% b', #{a}) = #{s.inspect}")
- }
- end
+ bug13440 = '[ruby-core:80696] [Bug #13440]'
+ failures = []
+ 0.step(to: 50, by: 0.05) do |i|
+ n = (10**i).to_i
+ root = Integer.sqrt(n)
+ failures << n unless root*root <= n && (root+1)*(root+1) > n
+ end
+ assert_empty(failures, bug13440)
- def test_printf_di
- VS.reverse_each {|a|
- s = sprintf("%d", a)
- b = s.to_i
- assert_equal(a, b, "sprintf('%d', #{a}) = #{s.inspect}")
- s = sprintf("%i", a)
- b = s.to_i
- assert_equal(a, b, "sprintf('%i', #{a}) = #{s.inspect}")
- }
+ x = 0xffff_ffff_ffff_ffff
+ assert_equal(x, Integer.sqrt(x ** 2), "[ruby-core:95453]")
end
- def test_marshal
- VS.reverse_each {|a|
- s = Marshal.dump(a)
- b = Marshal.load(s)
- assert_equal(a, b, "Marshal.load(Marshal.dump(#{a}))")
- }
+ def test_bug_21217
+ assert_equal(0x10000 * 2**10, Integer.sqrt(0x100000008 * 2**20))
end
- def test_pack_ber
- template = "w"
- VS.reverse_each {|a|
- if a < 0
- assert_raise(ArgumentError) { [a].pack(template) }
- else
- s = [a].pack(template)
- b = s.unpack(template)[0]
- assert_equal(a, b, "[#{a}].pack(#{template.dump}).unpack(#{template.dump})")
- end
- }
- end
+ def test_fdiv
+ assert_equal(1.0, 1.fdiv(1))
+ assert_equal(0.5, 1.fdiv(2))
- def test_pack_utf8
- template = "U"
- VS.reverse_each {|a|
- if a < 0 || 0x7fffffff < a
- assert_raise(RangeError) { [a].pack(template) }
- else
- s = [a].pack(template)
- b = s.unpack(template)[0]
- assert_equal(a, b, "[#{a}].pack(#{template.dump}).unpack(#{template.dump})")
- end
- }
+ m = 50 << Float::MANT_DIG
+ prev = 1.0
+ (1..100).each do |i|
+ val = (m + i).fdiv(m)
+ assert_operator val, :>=, prev, "1+epsilon*(#{i}/100)"
+ prev = val
+ end
end
- def test_Integer
- assert_raise(ArgumentError) {Integer("0x-1")}
- assert_raise(ArgumentError) {Integer("-0x-1")}
- assert_raise(ArgumentError) {Integer("0x 123")}
- assert_raise(ArgumentError) {Integer("0x 123")}
- assert_raise(ArgumentError) {Integer("0x0x5")}
- assert_raise(ArgumentError) {Integer("0x0x000000005")}
- assert_nothing_raised(ArgumentError) {
- assert_equal(1540841, "0x0x5".to_i(36))
- }
- assert_raise(ArgumentError) { Integer("--0") }
- assert_raise(ArgumentError) { Integer("-+0") }
- assert_raise(ArgumentError) { Integer("++1") }
- assert_raise(ArgumentError) { Integer("") }
- assert_raise(ArgumentError) { Integer("10 x") }
- assert_raise(ArgumentError) { Integer("1__2") }
- assert_raise(ArgumentError) { Integer("1z") }
- assert_raise(ArgumentError) { Integer("46116860184273__87904") }
- assert_raise(ArgumentError) { Integer("4611686018427387904_") }
- assert_raise(ArgumentError) { Integer("4611686018427387904 :") }
- assert_equal(0x4000000000000000, Integer("46_11_686_0184273_87904"))
- assert_raise(ArgumentError) { Integer("\0") }
- assert_nothing_raised(ArgumentError, "[ruby-core:13873]") {
- assert_equal(0, Integer("0 "))
- }
- assert_nothing_raised(ArgumentError, "[ruby-core:14139]") {
- assert_equal(0377, Integer("0_3_7_7"))
- }
- assert_raise(ArgumentError, "[ruby-core:14139]") {Integer("0__3_7_7")}
+ def test_obj_fdiv
+ o = Object.new
+ def o.coerce(x); [x, 0.5]; end
+ assert_equal(2.0, 1.fdiv(o))
+ o = Object.new
+ def o.coerce(x); [self, x]; end
+ def o.fdiv(x); 1; end
+ assert_equal(1.0, 1.fdiv(o))
+ end
+
+ def test_try_convert
+ assert_equal(1, Integer.try_convert(1))
+ assert_equal(1, Integer.try_convert(1.0))
+ assert_nil Integer.try_convert("1")
+ o = Object.new
+ assert_nil Integer.try_convert(o)
+ def o.to_i; 1; end
+ assert_nil Integer.try_convert(o)
+ o = Object.new
+ def o.to_int; 1; end
+ assert_equal(1, Integer.try_convert(o))
+
+ o = Object.new
+ 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))
+
+ o = Object.new
+ def o.coerce(other); [other, 10]; end
+ assert_equal(124, 1234.ceildiv(o))
end
end