summaryrefslogtreecommitdiff
path: root/test/ruby/test_float.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby/test_float.rb')
-rw-r--r--test/ruby/test_float.rb368
1 files changed, 356 insertions, 12 deletions
diff --git a/test/ruby/test_float.rb b/test/ruby/test_float.rb
index f1e01fc249..d0d180593a 100644
--- a/test/ruby/test_float.rb
+++ b/test/ruby/test_float.rb
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
require 'test/unit'
class TestFloat < Test::Unit::TestCase
@@ -15,6 +16,8 @@ class TestFloat < Test::Unit::TestCase
assert_in_delta(13.4 % 1, 0.4, 0.0001)
assert_equal(36893488147419111424,
36893488147419107329.0.to_i)
+ assert_equal(1185151044158398820374743613440,
+ 1.1851510441583988e+30.to_i)
end
def nan_test(x,y)
@@ -126,9 +129,9 @@ class TestFloat < Test::Unit::TestCase
assert_in_delta(a, 0, Float::EPSILON)
a = Float("-.0")
assert_in_delta(a, 0, Float::EPSILON)
- assert_raise(ArgumentError){Float("0.")}
- assert_raise(ArgumentError){Float("+0.")}
- assert_raise(ArgumentError){Float("-0.")}
+ assert_equal(0.0, Float("0."))
+ assert_equal(0.0, Float("+0."))
+ assert_equal(0.0, Float("-0."))
assert_raise(ArgumentError){Float(".")}
assert_raise(ArgumentError){Float("+")}
assert_raise(ArgumentError){Float("+.")}
@@ -136,9 +139,12 @@ class TestFloat < Test::Unit::TestCase
assert_raise(ArgumentError){Float("-.")}
assert_raise(ArgumentError){Float("1e")}
assert_raise(ArgumentError){Float("1__1")}
- assert_raise(ArgumentError){Float("1.")}
- assert_raise(ArgumentError){Float("1.e+00")}
- assert_raise(ArgumentError){Float("0x1.p+0")}
+ assert_equal(1.0, Float("1."))
+ assert_equal(1.0, Float("1.e+00"))
+ assert_equal(0.0625, Float("0x.1"))
+ assert_equal(1.0, Float("0x1."))
+ assert_equal(1.0, Float("0x1.0"))
+ assert_equal(1.0, Float("0x1.p+0"))
# add expected behaviour here.
assert_equal(10, Float("1_0"))
@@ -160,6 +166,32 @@ class TestFloat < Test::Unit::TestCase
assert_equal(-31.0*2**-1027, Float("-0x1f"+("0"*268)+".0p-2099"))
assert_equal(-31.0*2**-1027, Float("-0x1f"+("0"*600)+".0p-3427"))
end
+
+ assert_equal(1.0e10, Float("1.0_"+"00000"*Float::DIG+"e10"))
+
+ z = "0" * (Float::DIG * 4 + 10)
+ all_assertions_foreach("long invalid string", "1.0", "1.0e", "1.0e-", "1.0e+") do |n|
+ assert_raise(ArgumentError, n += z + "A") {Float(n)}
+ assert_raise(ArgumentError, n += z + ".0") {Float(n)}
+ end
+
+ x = nil
+ 2000.times do
+ x = Float("0x"+"0"*30)
+ break unless x == 0.0
+ end
+ assert_equal(0.0, x, ->{"%a" % x})
+ x = nil
+ 2000.times do
+ begin
+ x = Float("0x1."+"0"*270)
+ rescue ArgumentError => e
+ raise unless /"0x1\.0{270}"/ =~ e.message
+ else
+ break
+ end
+ end
+ assert_equal(1.0, x, ->{"%a" % x})
end
def test_divmod
@@ -195,6 +227,12 @@ class TestFloat < Test::Unit::TestCase
assert_equal(-3.5, (-11.5).remainder(-4))
assert_predicate(Float::NAN.remainder(4), :nan?)
assert_predicate(4.remainder(Float::NAN), :nan?)
+
+ ten = Object.new
+ def ten.coerce(other)
+ [other, 10]
+ end
+ assert_equal(4, 14.0.remainder(ten))
end
def test_to_s
@@ -294,6 +332,7 @@ class TestFloat < Test::Unit::TestCase
assert_equal(1.0, 1.0 ** (2**32))
assert_equal(1.0, 1.0 ** 1.0)
assert_raise(TypeError) { 1.0 ** nil }
+ assert_equal(9.0, 3.0 ** 2)
end
def test_eql
@@ -427,6 +466,11 @@ class TestFloat < Test::Unit::TestCase
assert_equal(1.110, 1.111.round(2))
assert_equal(11110.0, 11111.1.round(-1))
assert_equal(11100.0, 11111.1.round(-2))
+ assert_equal(-1.100, -1.111.round(1))
+ assert_equal(-1.110, -1.111.round(2))
+ assert_equal(-11110.0, -11111.1.round(-1))
+ assert_equal(-11100.0, -11111.1.round(-2))
+ assert_equal(0, 11111.1.round(-5))
assert_equal(10**300, 1.1e300.round(-300))
assert_equal(-10**300, -1.1e300.round(-300))
@@ -441,6 +485,112 @@ class TestFloat < Test::Unit::TestCase
assert_raise(TypeError) {1.0.round(nil)}
def (prec = Object.new).to_int; 2; end
assert_equal(1.0, 0.998.round(prec))
+
+ assert_equal(+5.02, +5.015.round(2))
+ assert_equal(-5.02, -5.015.round(2))
+ assert_equal(+1.26, +1.255.round(2))
+ assert_equal(-1.26, -1.255.round(2))
+ end
+
+ def test_round_half_even_with_precision
+ assert_equal(767573.18759, 767573.1875850001.round(5, half: :even))
+ assert_equal(767573.18758, 767573.187585.round(5, half: :even))
+ assert_equal(767573.18758, 767573.1875849998.round(5, half: :even))
+ assert_equal(767573.18758, 767573.187575.round(5, half: :even))
+ assert_equal(-767573.18759, -767573.1875850001.round(5, half: :even))
+ assert_equal(-767573.18758, -767573.187585.round(5, half: :even))
+ assert_equal(-767573.18758, -767573.1875849998.round(5, half: :even))
+ assert_equal(-767573.18758, -767573.187575.round(5, half: :even))
+ end
+
+ def test_floor_with_precision
+ assert_equal(+0.0, +0.001.floor(1))
+ assert_equal(-0.1, -0.001.floor(1))
+ assert_equal(1.100, 1.111.floor(1))
+ assert_equal(1.110, 1.111.floor(2))
+ assert_equal(11110, 11119.9.floor(-1))
+ assert_equal(11100, 11100.0.floor(-2))
+ assert_equal(11100, 11199.9.floor(-2))
+ assert_equal(-1.200, -1.111.floor(1))
+ assert_equal(-1.120, -1.111.floor(2))
+ assert_equal(-11120, -11119.9.floor(-1))
+ assert_equal(-11100, -11100.0.floor(-2))
+ assert_equal(-11200, -11199.9.floor(-2))
+ assert_equal(0, 11111.1.floor(-5))
+
+ assert_equal(10**300, 1.1e300.floor(-300))
+ assert_equal(-2*10**300, -1.1e300.floor(-300))
+ assert_equal(1.0e-300, 1.1e-300.floor(300))
+ assert_equal(-2.0e-300, -1.1e-300.floor(300))
+
+ assert_equal(42.0, 42.0.floor(308))
+ assert_equal(1.0e307, 1.0e307.floor(2))
+
+ assert_raise(TypeError) {1.0.floor("4")}
+ assert_raise(TypeError) {1.0.floor(nil)}
+ def (prec = Object.new).to_int; 2; end
+ assert_equal(0.99, 0.998.floor(prec))
+
+ assert_equal(-10000000000, -1.0.floor(-10), "[Bug #20654]")
+ assert_equal(-100000000000000000000, -1.0.floor(-20), "[Bug #20654]")
+ assert_equal(-100000000000000000000000000000000000000000000000000, -1.0.floor(-50), "[Bug #20654]")
+ end
+
+ def test_ceil_with_precision
+ assert_equal(+0.1, +0.001.ceil(1))
+ assert_equal(-0.0, -0.001.ceil(1))
+ 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(-1.100, -1.111.ceil(1))
+ assert_equal(-1.110, -1.111.ceil(2))
+ assert_equal(-11110, -11111.1.ceil(-1))
+ assert_equal(-11100, -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))
+
+ assert_equal(10000000000, 1.0.ceil(-10), "[Bug #20654]")
+ assert_equal(100000000000000000000, 1.0.ceil(-20), "[Bug #20654]")
+ assert_equal(100000000000000000000000000000000000000000000000000, 1.0.ceil(-50), "[Bug #20654]")
+ end
+
+ def test_truncate_with_precision
+ assert_equal(1.100, 1.111.truncate(1))
+ assert_equal(1.110, 1.111.truncate(2))
+ assert_equal(11110, 11119.9.truncate(-1))
+ assert_equal(11100, 11100.0.truncate(-2))
+ assert_equal(11100, 11199.9.truncate(-2))
+ assert_equal(-1.100, -1.111.truncate(1))
+ assert_equal(-1.110, -1.111.truncate(2))
+ assert_equal(-11110, -11111.1.truncate(-1))
+ assert_equal(-11100, -11111.1.truncate(-2))
+ assert_equal(0, 11111.1.truncate(-5))
+
+ assert_equal(10**300, 1.1e300.truncate(-300))
+ assert_equal(-10**300, -1.1e300.truncate(-300))
+ assert_equal(1.0e-300, 1.1e-300.truncate(300))
+ assert_equal(-1.0e-300, -1.1e-300.truncate(300))
+
+ assert_equal(42.0, 42.0.truncate(308))
+ assert_equal(1.0e307, 1.0e307.truncate(2))
+
+ assert_raise(TypeError) {1.0.truncate("4")}
+ assert_raise(TypeError) {1.0.truncate(nil)}
+ def (prec = Object.new).to_int; 2; end
+ assert_equal(0.99, 0.998.truncate(prec))
end
VS = [
@@ -570,9 +720,111 @@ class TestFloat < Test::Unit::TestCase
}
end
+ def test_round_half_even
+ assert_equal(12.0, 12.5.round(half: :even))
+ assert_equal(14.0, 13.5.round(half: :even))
+
+ assert_equal(2.2, 2.15.round(1, half: :even))
+ assert_equal(2.2, 2.25.round(1, half: :even))
+ assert_equal(2.4, 2.35.round(1, half: :even))
+
+ assert_equal(-2.2, -2.15.round(1, half: :even))
+ assert_equal(-2.2, -2.25.round(1, half: :even))
+ assert_equal(-2.4, -2.35.round(1, half: :even))
+
+ assert_equal(7.1364, 7.13645.round(4, half: :even))
+ assert_equal(7.1365, 7.1364501.round(4, half: :even))
+ assert_equal(7.1364, 7.1364499.round(4, half: :even))
+
+ assert_equal(-7.1364, -7.13645.round(4, half: :even))
+ assert_equal(-7.1365, -7.1364501.round(4, half: :even))
+ assert_equal(-7.1364, -7.1364499.round(4, half: :even))
+ end
+
+ def test_round_half_up
+ assert_equal(13.0, 12.5.round(half: :up))
+ assert_equal(14.0, 13.5.round(half: :up))
+
+ assert_equal(2.2, 2.15.round(1, half: :up))
+ assert_equal(2.3, 2.25.round(1, half: :up))
+ assert_equal(2.4, 2.35.round(1, half: :up))
+
+ assert_equal(-2.2, -2.15.round(1, half: :up))
+ assert_equal(-2.3, -2.25.round(1, half: :up))
+ assert_equal(-2.4, -2.35.round(1, half: :up))
+
+ assert_equal(7.1365, 7.13645.round(4, half: :up))
+ assert_equal(7.1365, 7.1364501.round(4, half: :up))
+ assert_equal(7.1364, 7.1364499.round(4, half: :up))
+
+ assert_equal(-7.1365, -7.13645.round(4, half: :up))
+ assert_equal(-7.1365, -7.1364501.round(4, half: :up))
+ assert_equal(-7.1364, -7.1364499.round(4, half: :up))
+ end
+
+ def test_round_half_down
+ assert_equal(12.0, 12.5.round(half: :down))
+ assert_equal(13.0, 13.5.round(half: :down))
+
+ assert_equal(2.1, 2.15.round(1, half: :down))
+ assert_equal(2.2, 2.25.round(1, half: :down))
+ assert_equal(2.3, 2.35.round(1, half: :down))
+
+ assert_equal(-2.1, -2.15.round(1, half: :down))
+ assert_equal(-2.2, -2.25.round(1, half: :down))
+ assert_equal(-2.3, -2.35.round(1, half: :down))
+
+ assert_equal(7.1364, 7.13645.round(4, half: :down))
+ assert_equal(7.1365, 7.1364501.round(4, half: :down))
+ assert_equal(7.1364, 7.1364499.round(4, half: :down))
+
+ assert_equal(-7.1364, -7.13645.round(4, half: :down))
+ assert_equal(-7.1365, -7.1364501.round(4, half: :down))
+ assert_equal(-7.1364, -7.1364499.round(4, half: :down))
+ end
+
+ def test_round_half_nil
+ assert_equal(13.0, 12.5.round(half: nil))
+ assert_equal(14.0, 13.5.round(half: nil))
+
+ assert_equal(2.2, 2.15.round(1, half: nil))
+ assert_equal(2.3, 2.25.round(1, half: nil))
+ assert_equal(2.4, 2.35.round(1, half: nil))
+
+ assert_equal(-2.2, -2.15.round(1, half: nil))
+ assert_equal(-2.3, -2.25.round(1, half: nil))
+ assert_equal(-2.4, -2.35.round(1, half: nil))
+
+ assert_equal(7.1365, 7.13645.round(4, half: nil))
+ assert_equal(7.1365, 7.1364501.round(4, half: nil))
+ assert_equal(7.1364, 7.1364499.round(4, half: nil))
+
+ assert_equal(-7.1365, -7.13645.round(4, half: nil))
+ assert_equal(-7.1365, -7.1364501.round(4, half: nil))
+ assert_equal(-7.1364, -7.1364499.round(4, half: nil))
+ end
+
+ def test_round_half_invalid
+ assert_raise_with_message(ArgumentError, /Object/) {
+ 1.0.round(half: Object)
+ }
+ assert_raise_with_message(ArgumentError, /xxx/) {
+ 1.0.round(half: "\0xxx")
+ }
+ assert_raise_with_message(Encoding::CompatibilityError, /ASCII incompatible/) {
+ 1.0.round(half: "up".force_encoding("utf-16be"))
+ }
+ end
+
def test_Float
assert_in_delta(0.125, Float("0.1_2_5"), 0.00001)
assert_in_delta(0.125, "0.1_2_5__".to_f, 0.00001)
+ assert_in_delta(0.0, "0_.125".to_f, 0.00001)
+ assert_in_delta(0.0, "0._125".to_f, 0.00001)
+ assert_in_delta(0.1, "0.1__2_5".to_f, 0.00001)
+ assert_in_delta(0.1, "0.1_e10".to_f, 0.00001)
+ assert_in_delta(0.1, "0.1e_10".to_f, 0.00001)
+ assert_in_delta(1.0, "0.1e1__0".to_f, 0.00001)
assert_equal(1, suppress_warning {Float(([1] * 10000).join)}.infinite?)
assert_not_predicate(Float(([1] * 10000).join("_")), :infinite?) # is it really OK?
assert_raise(ArgumentError) { Float("1.0\x001") }
@@ -581,17 +833,37 @@ class TestFloat < Test::Unit::TestCase
assert_equal(15, Float('0xf'))
assert_equal(15, Float('0xfp0'))
assert_raise(ArgumentError) { Float('0xfp') }
- assert_raise(ArgumentError) { Float('0xf.') }
+ assert_equal(15, Float('0xf.'))
assert_raise(ArgumentError) { Float('0xf.p') }
- assert_raise(ArgumentError) { Float('0xf.p0') }
- assert_raise(ArgumentError) { Float('0xf.f') }
+ assert_equal(15, Float('0xf.p0'))
+ assert_equal(15.9375, Float('0xf.f'))
assert_raise(ArgumentError) { Float('0xf.fp') }
- assert_equal(Float::INFINITY, Float('0xf.fp1000000000000000'))
+ assert_equal(0x10a, Float("0x1_0a"))
+ assert_equal(1.625, Float("0x1.a_0"))
+ assert_equal(3.25, Float("0x1.ap0_1"))
+ assert_raise(ArgumentError) { Float("0x1.ap0a") }
+ begin
+ verbose_bak, $VERBOSE = $VERBOSE, nil
+ assert_equal(Float::INFINITY, Float('0xf.fp1000000000000000'))
+ ensure
+ $VERBOSE = verbose_bak
+ end
assert_equal(1, suppress_warning {Float("1e10_00")}.infinite?)
assert_raise(TypeError) { Float(nil) }
+ assert_raise(TypeError) { Float(:test) }
o = Object.new
def o.to_f; inf = Float::INFINITY; inf/inf; end
assert_predicate(Float(o), :nan?)
+
+ assert_raise(Encoding::CompatibilityError) {Float("0".encode("utf-16be"))}
+ assert_raise(Encoding::CompatibilityError) {Float("0".encode("utf-16le"))}
+ assert_raise(Encoding::CompatibilityError) {Float("0".encode("utf-32be"))}
+ assert_raise(Encoding::CompatibilityError) {Float("0".encode("utf-32le"))}
+ assert_raise(Encoding::CompatibilityError) {Float("0".encode("iso-2022-jp"))}
+
+ EnvUtil.with_default_internal(Encoding::UTF_8) do
+ assert_raise_with_message(ArgumentError, /\u{1f4a1}/) {Float("\u{1f4a1}")}
+ end
end
def test_invalid_str
@@ -599,8 +871,51 @@ class TestFloat < Test::Unit::TestCase
assert_raise(ArgumentError, bug4310) {under_gc_stress {Float('a'*10000)}}
end
+ def test_Float_with_invalid_exception
+ assert_raise(ArgumentError) {
+ Float("0", exception: 1)
+ }
+ end
+
+ def test_Float_with_exception_keyword
+ assert_raise(ArgumentError) {
+ Float(".", exception: true)
+ }
+ assert_nothing_raised(ArgumentError) {
+ assert_equal(nil, Float(".", exception: false))
+ }
+ assert_raise(RangeError) {
+ Float(1i, exception: true)
+ }
+ assert_nothing_raised(RangeError) {
+ assert_equal(nil, Float(1i, exception: false))
+ }
+ assert_raise(TypeError) {
+ Float(nil, exception: true)
+ }
+ assert_nothing_raised(TypeError) {
+ assert_equal(nil, Float(nil, exception: false))
+ }
+ assert_nothing_raised(TypeError) {
+ assert_equal(nil, Float(:test, exception: false))
+ }
+ assert_nothing_raised(TypeError) {
+ assert_equal(nil, Float(Object.new, exception: false))
+ }
+ assert_nothing_raised(TypeError) {
+ o = Object.new
+ def o.to_f; 3.14; end
+ assert_equal(3.14, Float(o, exception: false))
+ }
+ assert_nothing_raised(RuntimeError) {
+ o = Object.new
+ def o.to_f; raise; end
+ assert_equal(nil, Float(o, exception: false))
+ }
+ end
+
def test_num2dbl
- assert_raise(ArgumentError) do
+ assert_raise(ArgumentError, "comparison of String with 0 failed") do
1.0.step(2.0, "0.5") {}
end
assert_raise(TypeError) do
@@ -627,6 +942,11 @@ class TestFloat < Test::Unit::TestCase
end
assert_equal([5.0, 4.0, 3.0, 2.0], 5.0.step(1.5, -1).to_a)
+
+ assert_equal(11, ((0.24901079128550474)..(340.2500808898068)).step(34.00010700985213).to_a.size)
+ assert_equal(11, ((0.24901079128550474)..(340.25008088980684)).step(34.00010700985213).to_a.size)
+ assert_equal(11, ((-0.24901079128550474)..(-340.2500808898068)).step(-34.00010700985213).to_a.size)
+ assert_equal(11, ((-0.24901079128550474)..(-340.25008088980684)).step(-34.00010700985213).to_a.size)
end
def test_step2
@@ -638,7 +958,9 @@ class TestFloat < Test::Unit::TestCase
a = rand
b = a+rand*1000
s = (b - a) / 10
- assert_equal(10, (a...b).step(s).to_a.length)
+ b = a + s*9.999999
+ seq = (a...b).step(s)
+ assert_equal(10, seq.to_a.length, seq.inspect)
end
assert_equal([1.0, 2.9, 4.8, 6.699999999999999], (1.0...6.8).step(1.9).to_a)
@@ -647,6 +969,11 @@ class TestFloat < Test::Unit::TestCase
(1.0 ... e).step(1E-16) do |n|
assert_operator(n, :<=, e)
end
+
+ assert_equal(10, ((0.24901079128550474)...(340.2500808898068)).step(34.00010700985213).to_a.size)
+ assert_equal(11, ((0.24901079128550474)...(340.25008088980684)).step(34.00010700985213).to_a.size)
+ assert_equal(10, ((-0.24901079128550474)...(-340.2500808898068)).step(-34.00010700985213).to_a.size)
+ assert_equal(11, ((-0.24901079128550474)...(-340.25008088980684)).step(-34.00010700985213).to_a.size)
end
def test_singleton_method
@@ -704,4 +1031,21 @@ class TestFloat < Test::Unit::TestCase
h = {0.0 => bug10979}
assert_equal(bug10979, h[-0.0])
end
+
+ def test_aliased_quo_recursion
+ assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
+ begin;
+ class Float
+ $VERBOSE = nil
+ alias / quo
+ end
+ assert_raise(NameError) do
+ begin
+ 1.0/2.0
+ rescue SystemStackError => e
+ raise SystemStackError, e.message
+ end
+ end
+ end;
+ end
end