1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/test/ruby/test_float.rb

431 lines
10 KiB
Ruby
Raw Normal View History

require 'test/unit'
class TestFloat < Test::Unit::TestCase
def test_float
assert_equal(2, 2.6.floor)
assert_equal(-3, (-2.6).floor)
assert_equal(3, 2.6.ceil)
assert_equal(-2, (-2.6).ceil)
assert_equal(2, 2.6.truncate)
assert_equal(-2, (-2.6).truncate)
assert_equal(3, 2.6.round)
assert_equal(-2, (-2.4).truncate)
assert((13.4 % 1 - 0.4).abs < 0.0001)
assert_equal(36893488147419111424,
36893488147419107329.0.to_i)
end
def nan_test(x,y)
extend Test::Unit::Assertions
assert(x != y)
assert_equal(false, (x < y))
assert_equal(false, (x > y))
assert_equal(false, (x <= y))
assert_equal(false, (x >= y))
end
def test_nan
nan = 0.0/0
nan_test(nan, nan)
nan_test(nan, 0)
nan_test(nan, 1)
nan_test(nan, -1)
nan_test(nan, 1000)
nan_test(nan, -1000)
nan_test(nan, 1_000_000_000_000)
nan_test(nan, -1_000_000_000_000)
nan_test(nan, 100.0);
nan_test(nan, -100.0);
nan_test(nan, 0.001);
nan_test(nan, -0.001);
nan_test(nan, 1.0/0);
nan_test(nan, -1.0/0);
end
def test_precision
u = 3.7517675036461267e+17
v = sprintf("%.16e", u).to_f
assert_in_delta(u, v, u.abs * Float::EPSILON)
assert_in_delta(u, v, v.abs * Float::EPSILON)
end
def test_symmetry_bignum # [ruby-bugs-ja:118]
a = 100000000000000000000000
b = 100000000000000000000000.0
assert_equal(a == b, b == a)
end
def test_strtod
a = Float("0")
assert(a.abs < Float::EPSILON)
a = Float("0.0")
assert(a.abs < Float::EPSILON)
a = Float("+0.0")
assert(a.abs < Float::EPSILON)
a = Float("-0.0")
assert(a.abs < Float::EPSILON)
a = Float("0.0000000000000000001")
assert(a != 0.0)
a = Float("+0.0000000000000000001")
assert(a != 0.0)
a = Float("-0.0000000000000000001")
assert(a != 0.0)
a = Float(".0")
assert(a.abs < Float::EPSILON)
a = Float("+.0")
assert(a.abs < Float::EPSILON)
a = Float("-.0")
assert(a.abs < Float::EPSILON)
assert_raise(ArgumentError){Float(".")}
assert_raise(ArgumentError){Float("+")}
assert_raise(ArgumentError){Float("+.")}
assert_raise(ArgumentError){Float("-")}
assert_raise(ArgumentError){Float("-.")}
assert_raise(ArgumentError){Float("1e")}
assert_raise(ArgumentError){Float("1__1")}
# add expected behaviour here.
assert_equal(10, Float("1_0"))
end
* sprintf.c (rb_str_format): allow %c to print one character string (e.g. ?x). * lib/tempfile.rb (Tempfile::make_tmpname): put dot between basename and pid. [ruby-talk:196272] * parse.y (do_block): remove -> style block. * parse.y (parser_yylex): remove tLAMBDA_ARG. * eval.c (rb_call0): binding for the return event hook should have consistent scope. [ruby-core:07928] * eval.c (proc_invoke): return behavior should depend whether it is surrounded by a lambda or a mere block. * eval.c (formal_assign): handles post splat arguments. * eval.c (rb_call0): ditto. * st.c (strhash): use FNV-1a hash. * parse.y (parser_yylex): removed experimental ';;' terminator. * eval.c (rb_node_arity): should be aware of post splat arguments. * eval.c (rb_proc_arity): ditto. * parse.y (f_args): syntax rule enhanced to support arguments after the splat. * parse.y (block_param): ditto for block parameters. * parse.y (f_post_arg): mandatory formal arguments after the splat argument. * parse.y (new_args_gen): generate nodes for mandatory formal arguments after the splat argument. * eval.c (rb_eval): dispatch mandatory formal arguments after the splat argument. * parse.y (args): allow more than one splat in the argument list. * parse.y (method_call): allow aref [] to accept all kind of method argument, including assocs, splat, and block argument. * eval.c (SETUP_ARGS0): prepare block argument as well. * lib/mathn.rb (Integer): remove Integer#gcd2. [ruby-core:07931] * eval.c (error_line): print receivers true/false/nil specially. * eval.c (rb_proc_yield): handles parameters in yield semantics. * eval.c (nil_yield): gives LocalJumpError to denote no block error. * io.c (rb_io_getc): now takes one-character string. * string.c (rb_str_hash): use FNV-1a hash from Fowler/Noll/Vo hashing algorithm. * string.c (rb_str_aref): str[0] now returns 1 character string, instead of a fixnum. [Ruby2] * parse.y (parser_yylex): ?c now returns 1 character string, instead of a fixnum. [Ruby2] * string.c (rb_str_aset): no longer support fixnum insertion. * eval.c (umethod_bind): should not update original class. [ruby-dev:28636] * eval.c (ev_const_get): should support constant access from within instance_eval(). [ruby-dev:28327] * time.c (time_timeval): should round for usec floating number. [ruby-core:07896] * time.c (time_add): ditto. * dir.c (sys_warning): should not call a vararg function rb_sys_warning() indirectly. [ruby-core:07886] * numeric.c (flo_divmod): the first element of Float#divmod should be an integer. [ruby-dev:28589] * test/ruby/test_float.rb: add tests for divmod, div, modulo and remainder. * re.c (rb_reg_initialize): should not allow modifying literal regexps. frozen check moved from rb_reg_initialize_m as well. * re.c (rb_reg_initialize): should not modify untainted objects in safe levels higher than 3. * re.c (rb_memcmp): type change from char* to const void*. * dir.c (dir_close): should not close untainted dir stream. * dir.c (GetDIR): add tainted/frozen check for each dir operation. * lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_symbol_arg): typo fixed. a patch from Florian Gross <florg at florg.net>. * eval.c (EXEC_EVENT_HOOK): trace_func may remove itself from event_hooks. no guarantee for arbitrary hook deletion. [ruby-dev:28632] * util.c (ruby_strtod): differ addition to minimize error. [ruby-dev:28619] * util.c (ruby_strtod): should not raise ERANGE when the input string does not have any digits. [ruby-dev:28629] * eval.c (proc_invoke): should restore old ruby_frame->block. thanks to ts <decoux at moulon.inra.fr>. [ruby-core:07833] also fix [ruby-dev:28614] as well. * signal.c (trap): sig should be less then NSIG. Coverity found this bug. a patch from Kevin Tew <tewk at tewk.com>. [ruby-core:07823] * math.c (math_log2): add new method inspired by [ruby-talk:191237]. * math.c (math_log): add optional base argument to Math::log(). [ruby-talk:191308] * ext/syck/emitter.c (syck_scan_scalar): avoid accessing uninitialized array element. a patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07809] * array.c (rb_ary_fill): initialize local variables first. a patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07810] * ext/syck/yaml2byte.c (syck_yaml2byte_handler): need to free type_tag. a patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07808] * ext/socket/socket.c (make_hostent_internal): accept ai_family check from Sam Roberts <sroberts at uniserve.com>. [ruby-core:07691] * util.c (ruby_strtod): should not cut off 18 digits for no reason. [ruby-core:07796] * array.c (rb_ary_fill): internalize local variable "beg" to pacify Coverity. [ruby-core:07770] * pack.c (pack_unpack): now supports CRLF newlines. a patch from <tommy at tmtm.org>. [ruby-dev:28601] * applied code clean-up patch from Stefan Huehner <stefan at huehner.org>. [ruby-core:07764] * lib/jcode.rb (String::tr_s): should have translated non squeezing character sequence (i.e. a character) as well. thanks to Hiroshi Ichikawa <gimite at gimite.ddo.jp> [ruby-list:42090] * ext/socket/socket.c: document update patch from Sam Roberts <sroberts at uniserve.com>. [ruby-core:07701] * lib/mathn.rb (Integer): need not to remove gcd2. a patch from NARUSE, Yui <naruse at airemix.com>. [ruby-dev:28570] * parse.y (arg): too much NEW_LIST() * eval.c (SETUP_ARGS0): remove unnecessary access to nd_alen. * eval.c (rb_eval): use ARGSCAT for NODE_OP_ASGN1. [ruby-dev:28585] * parse.y (arg): use NODE_ARGSCAT for placeholder. * lib/getoptlong.rb (GetoptLong::get): RDoc update patch from mathew <meta at pobox.com>. [ruby-core:07738] * variable.c (rb_const_set): raise error when no target klass is supplied. [ruby-dev:28582] * prec.c (prec_prec_f): documentation patch from <gerardo.santana at gmail.com>. [ruby-core:07689] * bignum.c (rb_big_pow): second operand may be too big even if it's a Fixnum. [ruby-talk:187984] * README.EXT: update symbol description. [ruby-talk:188104] * COPYING: explicitly note GPLv2. [ruby-talk:187922] * parse.y: remove some obsolete syntax rules (unparenthesized method calls in argument list). * eval.c (rb_call0): insecure calling should be checked for non NODE_SCOPE method invocations too. * eval.c (rb_alias): should preserve the current safe level as well as method definition. * process.c (rb_f_sleep): remove RDoc description about SIGALRM which is not valid on the current implementation. [ruby-dev:28464] Thu Mar 23 21:40:47 2006 K.Kosako <sndgk393 AT ybb.ne.jp> * eval.c (method_missing): should support argument splat in super. a bug in combination of super, splat and method_missing. [ruby-talk:185438] * configure.in: Solaris SunPro compiler -rapth patch from <kuwa at labs.fujitsu.com>. [ruby-dev:28443] * configure.in: remove enable_rpath=no for Solaris. [ruby-dev:28440] * ext/win32ole/win32ole.c (ole_val2olevariantdata): change behavior of converting OLE Variant object with VT_ARRAY|VT_UI1 and Ruby String object. * ruby.1: a clarification patch from David Lutterkort <dlutter at redhat.com>. [ruby-core:7508] * lib/rdoc/ri/ri_paths.rb (RI::Paths): adding paths from rubygems directories. a patch from Eric Hodel <drbrain at segment7.net>. [ruby-core:07423] * eval.c (rb_clear_cache_by_class): clearing wrong cache. * ext/extmk.rb: use :remove_destination to install extension libraries to avoid SEGV. [ruby-dev:28417] * eval.c (rb_thread_fd_writable): should not re-schedule output from KILLED thread (must be error printing). * array.c (rb_ary_flatten_bang): allow specifying recursion level. [ruby-talk:182170] * array.c (rb_ary_flatten): ditto. * gc.c (add_heap): a heap_slots may overflow. a patch from Stefan Weil <weil at mail.berlios.de>. * eval.c (rb_call): use separate cache for fcall/vcall invocation. * eval.c (rb_eval): NODE_FCALL, NODE_VCALL can call local functions. * eval.c (rb_mod_local): a new method to specify newly added visibility "local". * eval.c (search_method): search for local methods which are visible only from the current class. * class.c (rb_class_local_methods): a method to list local methods. * object.c (Init_Object): add BasicObject class as a top level BlankSlate class. * ruby.h (SYM2ID): should not cast to signed long. [ruby-core:07414] * class.c (rb_include_module): allow module duplication. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10235 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2006-06-09 17:20:17 -04:00
def test_divmod
assert_equal([2, 3.5], 11.5.divmod(4))
assert_equal([-3, -0.5], 11.5.divmod(-4))
assert_equal([-3, 0.5], (-11.5).divmod(4))
assert_equal([2, -3.5], (-11.5).divmod(-4))
end
def test_div
assert_equal(2, 11.5.div(4))
assert_equal(-3, 11.5.div(-4))
assert_equal(-3, (-11.5).div(4))
assert_equal(2, (-11.5).div(-4))
end
def test_modulo
assert_equal(3.5, 11.5.modulo(4))
assert_equal(-0.5, 11.5.modulo(-4))
assert_equal(0.5, (-11.5).modulo(4))
assert_equal(-3.5, (-11.5).modulo(-4))
end
def test_remainder
assert_equal(3.5, 11.5.remainder(4))
assert_equal(3.5, 11.5.remainder(-4))
assert_equal(-3.5, (-11.5).remainder(4))
assert_equal(-3.5, (-11.5).remainder(-4))
end
def test_to_s
inf = 1.0 / 0.0
assert_equal("Infinity", inf.to_s)
assert_equal("-Infinity", (-inf).to_s)
assert_equal("NaN", (inf / inf).to_s)
assert_equal("1.0e+14", 10000_00000_00000.0.to_s)
end
def test_coerce
assert_equal(Float, 1.0.coerce(1).first.class)
end
def test_plus
assert_equal(4.0, 2.0.send(:+, 2))
assert_equal(4.0, 2.0.send(:+, (2**32).coerce(2).first))
assert_equal(4.0, 2.0.send(:+, 2.0))
assert_raise(TypeError) { 2.0.send(:+, nil) }
end
def test_minus
assert_equal(0.0, 2.0.send(:-, 2))
assert_equal(0.0, 2.0.send(:-, (2**32).coerce(2).first))
assert_equal(0.0, 2.0.send(:-, 2.0))
assert_raise(TypeError) { 2.0.send(:-, nil) }
end
def test_mul
assert_equal(4.0, 2.0.send(:*, 2))
assert_equal(4.0, 2.0.send(:*, (2**32).coerce(2).first))
assert_equal(4.0, 2.0.send(:*, 2.0))
assert_raise(TypeError) { 2.0.send(:*, nil) }
end
def test_div2
assert_equal(1.0, 2.0.send(:/, 2))
assert_equal(1.0, 2.0.send(:/, (2**32).coerce(2).first))
assert_equal(1.0, 2.0.send(:/, 2.0))
assert_raise(TypeError) { 2.0.send(:/, nil) }
end
def test_modulo2
assert_equal(0.0, 2.0.send(:%, 2))
assert_equal(0.0, 2.0.send(:%, (2**32).coerce(2).first))
assert_equal(0.0, 2.0.send(:%, 2.0))
assert_raise(TypeError) { 2.0.send(:%, nil) }
end
def test_divmod2
assert_equal([1.0, 0.0], 2.0.divmod(2))
assert_equal([1.0, 0.0], 2.0.divmod((2**32).coerce(2).first))
assert_equal([1.0, 0.0], 2.0.divmod(2.0))
assert_raise(TypeError) { 2.0.divmod(nil) }
inf = 1.0 / 0.0
a, b = inf.divmod(0)
assert(a.infinite?)
assert(b.nan?)
a, b = (2.0**32).divmod(1.0)
assert_equal(2**32, a)
assert_equal(0, b)
end
def test_pow
assert_equal(1.0, 1.0 ** (2**32))
assert_equal(1.0, 1.0 ** 1.0)
assert_raise(TypeError) { 1.0 ** nil }
end
def test_eql
inf = 1.0 / 0.0
nan = inf / inf
assert(1.0.eql?(1.0))
assert(inf.eql?(inf))
assert(!(nan.eql?(nan)))
assert(!(1.0.eql?(nil)))
assert(1.0 == 1)
assert(1.0 != 2**32)
assert(1.0 != nan)
assert(1.0 != nil)
end
def test_cmp
inf = 1.0 / 0.0
nan = inf / inf
assert_equal(0, 1.0 <=> 1.0)
assert_equal(1, 1.0 <=> 0.0)
assert_equal(-1, 1.0 <=> 2.0)
assert_nil(1.0 <=> nil)
assert_nil(1.0 <=> nan)
assert_nil(nan <=> 1.0)
assert_equal(0, 1.0 <=> 1)
assert_equal(1, 1.0 <=> 0)
assert_equal(-1, 1.0 <=> 2)
assert_equal(-1, 1.0 <=> 2**32)
assert_raise(ArgumentError) { 1.0 > nil }
assert_raise(ArgumentError) { 1.0 >= nil }
assert_raise(ArgumentError) { 1.0 < nil }
assert_raise(ArgumentError) { 1.0 <= nil }
end
def test_zero_p
assert(0.0.zero?)
assert(!(1.0.zero?))
end
def test_infinite_p
inf = 1.0 / 0.0
assert(1, inf.infinite?)
assert(1, (-inf).infinite?)
assert_nil(1.0.infinite?)
end
def test_finite_p
inf = 1.0 / 0.0
assert(!(inf.finite?))
assert(!((-inf).finite?))
assert(1.0.finite?)
end
def test_floor_ceil_round_truncate
assert_equal(1, 1.5.floor)
assert_equal(2, 1.5.ceil)
assert_equal(2, 1.5.round)
assert_equal(1, 1.5.truncate)
assert_equal(2, 2.0.floor)
assert_equal(2, 2.0.ceil)
assert_equal(2, 2.0.round)
assert_equal(2, 2.0.truncate)
assert_equal(-2, (-1.5).floor)
assert_equal(-1, (-1.5).ceil)
assert_equal(-2, (-1.5).round)
assert_equal(-1, (-1.5).truncate)
assert_equal(-2, (-2.0).floor)
assert_equal(-2, (-2.0).ceil)
assert_equal(-2, (-2.0).round)
assert_equal(-2, (-2.0).truncate)
inf = 1.0/0.0
assert_raise(FloatDomainError) { inf.floor }
assert_raise(FloatDomainError) { inf.ceil }
assert_raise(FloatDomainError) { inf.round }
assert_raise(FloatDomainError) { inf.truncate }
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))
end
def test_induced_from
assert_equal(1.0, Float.induced_from(1))
assert_equal(1.0, Float.induced_from(1.0))
assert_raise(TypeError) { Float.induced_from(nil) }
end
VS = [
18446744073709551617.0,
18446744073709551616.0,
18446744073709551615.8,
18446744073709551615.5,
18446744073709551615.2,
18446744073709551615.0,
18446744073709551614.0,
4611686018427387905.0,
4611686018427387904.0,
4611686018427387903.8,
4611686018427387903.5,
4611686018427387903.2,
4611686018427387903.0,
4611686018427387902.0,
4294967297.0,
4294967296.0,
4294967295.8,
4294967295.5,
4294967295.2,
4294967295.0,
4294967294.0,
1073741825.0,
1073741824.0,
1073741823.8,
1073741823.5,
1073741823.2,
1073741823.0,
1073741822.0,
-1073741823.0,
-1073741824.0,
-1073741824.2,
-1073741824.5,
-1073741824.8,
-1073741825.0,
-1073741826.0,
-4294967295.0,
-4294967296.0,
-4294967296.2,
-4294967296.5,
-4294967296.8,
-4294967297.0,
-4294967298.0,
-4611686018427387903.0,
-4611686018427387904.0,
-4611686018427387904.2,
-4611686018427387904.5,
-4611686018427387904.8,
-4611686018427387905.0,
-4611686018427387906.0,
-18446744073709551615.0,
-18446744073709551616.0,
-18446744073709551616.2,
-18446744073709551616.5,
-18446744073709551616.8,
-18446744073709551617.0,
-18446744073709551618.0,
]
def test_truncate
VS.each {|f|
i = f.truncate
assert_equal(i, f.to_i)
if f < 0
assert_operator(i, :<, 0)
else
assert_operator(i, :>, 0)
end
assert_operator(i.abs, :<=, f.abs)
d = f.abs - i.abs
assert_operator(0, :<=, d)
assert_operator(d, :<, 1)
}
end
def test_ceil
VS.each {|f|
i = f.ceil
if f < 0
assert_operator(i, :<, 0)
else
assert_operator(i, :>, 0)
end
assert_operator(i, :>=, f)
d = f - i
assert_operator(-1, :<, d)
assert_operator(d, :<=, 0)
}
end
def test_floor
VS.each {|f|
i = f.floor
if f < 0
assert_operator(i, :<, 0)
else
assert_operator(i, :>, 0)
end
assert_operator(i, :<=, f)
d = f - i
assert_operator(0, :<=, d)
assert_operator(d, :<, 1)
}
end
def test_round
VS.each {|f|
i = f.round
if f < 0
assert_operator(i, :<, 0)
else
assert_operator(i, :>, 0)
end
d = f - i
assert_operator(-0.5, :<=, d)
assert_operator(d, :<=, 0.5)
}
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(Float(([1] * 10000).join).infinite?)
assert(!Float(([1] * 10000).join("_")).infinite?) # is it really OK?
assert_raise(ArgumentError) { Float("1.0\x001") }
assert(Float("1e10_00").infinite?)
assert_raise(TypeError) { Float(nil) }
o = Object.new
def o.to_f; inf = 1.0/0.0; inf/inf; end
assert_raise(ArgumentError) { Float(o) }
end
def test_num2dbl
assert_raise(TypeError) do
1.0.step(2.0, "0.5") {}
end
assert_raise(TypeError) do
1.0.step(2.0, nil) {}
end
end
end