1require_relative "testbase" 2require_relative "../ruby/envutil" 3 4require 'thread' 5 6class TestBigDecimal < Test::Unit::TestCase 7 include TestBigDecimalBase 8 9 ROUNDING_MODE_MAP = [ 10 [ BigDecimal::ROUND_UP, :up], 11 [ BigDecimal::ROUND_DOWN, :down], 12 [ BigDecimal::ROUND_DOWN, :truncate], 13 [ BigDecimal::ROUND_HALF_UP, :half_up], 14 [ BigDecimal::ROUND_HALF_UP, :default], 15 [ BigDecimal::ROUND_HALF_DOWN, :half_down], 16 [ BigDecimal::ROUND_HALF_EVEN, :half_even], 17 [ BigDecimal::ROUND_HALF_EVEN, :banker], 18 [ BigDecimal::ROUND_CEILING, :ceiling], 19 [ BigDecimal::ROUND_CEILING, :ceil], 20 [ BigDecimal::ROUND_FLOOR, :floor], 21 ] 22 23 def assert_nan(x) 24 assert(x.nan?, "Expected #{x.inspect} to be NaN") 25 end 26 27 def assert_positive_infinite(x) 28 assert(x.infinite?, "Expected #{x.inspect} to be positive infinite") 29 assert_operator(x, :>, 0) 30 end 31 32 def assert_negative_infinite(x) 33 assert(x.infinite?, "Expected #{x.inspect} to be negative infinite") 34 assert_operator(x, :<, 0) 35 end 36 37 def assert_positive_zero(x) 38 assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, x.sign, 39 "Expected #{x.inspect} to be positive zero") 40 end 41 42 def assert_negative_zero(x) 43 assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, x.sign, 44 "Expected #{x.inspect} to be negative zero") 45 end 46 47 def test_not_equal 48 assert_not_equal BigDecimal("1"), BigDecimal.allocate 49 end 50 51 def test_global_new 52 assert_equal(1, BigDecimal("1")) 53 assert_equal(1, BigDecimal("1", 1)) 54 assert_raise(ArgumentError) { BigDecimal("1", -1) } 55 assert_raise(ArgumentError) { BigDecimal(4.2) } 56 begin 57 BigDecimal(4.2) 58 rescue ArgumentError => error 59 assert_match(/Float/, error.message) 60 end 61 assert_raise(ArgumentError) { BigDecimal(42.quo(7)) } 62 begin 63 BigDecimal(42.quo(7)) 64 rescue ArgumentError => error 65 assert_match(/Rational/, error.message) 66 end 67 end 68 69 def test_global_new_with_integer 70 assert_equal(BigDecimal("1"), BigDecimal(1)) 71 assert_equal(BigDecimal("-1"), BigDecimal(-1)) 72 assert_equal(BigDecimal((2**100).to_s), BigDecimal(2**100)) 73 assert_equal(BigDecimal((-2**100).to_s), BigDecimal(-2**100)) 74 end 75 76 def test_global_new_with_rational 77 assert_equal(BigDecimal("0.333333333333333333333"), BigDecimal(1.quo(3), 21)) 78 assert_equal(BigDecimal("-0.333333333333333333333"), BigDecimal(-1.quo(3), 21)) 79 assert_raise(ArgumentError) { BigDecimal(1.quo(3)) } 80 end 81 82 def test_global_new_with_float 83 assert_equal(BigDecimal("0.1235"), BigDecimal(0.1234567, 4)) 84 assert_equal(BigDecimal("-0.1235"), BigDecimal(-0.1234567, 4)) 85 assert_raise(ArgumentError) { BigDecimal(0.1) } 86 assert_raise(ArgumentError) { BigDecimal(0.1, Float::DIG + 2) } 87 assert_nothing_raised { BigDecimal(0.1, Float::DIG + 1) } 88 end 89 90 def test_global_new_with_big_decimal 91 assert_equal(BigDecimal(1), BigDecimal(BigDecimal(1))) 92 assert_equal(BigDecimal('+0'), BigDecimal(BigDecimal('+0'))) 93 assert_equal(BigDecimal('-0'), BigDecimal(BigDecimal('-0'))) 94 BigDecimal.save_exception_mode do 95 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 96 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 97 assert_positive_infinite(BigDecimal(BigDecimal('Infinity'))) 98 assert_negative_infinite(BigDecimal(BigDecimal('-Infinity'))) 99 assert_nan(BigDecimal(BigDecimal('NaN'))) 100 end 101 end 102 103 def test_global_new_with_tainted_string 104 Thread.new { 105 $SAFE = 1 106 BigDecimal('1'.taint) 107 }.join 108 end 109 110 def test_new 111 assert_equal(1, BigDecimal.new("1")) 112 assert_equal(1, BigDecimal.new("1", 1)) 113 assert_equal(1, BigDecimal.new(" 1 ")) 114 assert_equal(111, BigDecimal.new("1_1_1_")) 115 assert_equal(0, BigDecimal.new("_1_1_1")) 116 assert_equal(10**(-1), BigDecimal.new("1E-1"), '#4825') 117 118 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 119 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 120 assert_equal( 1, BigDecimal.new("Infinity").infinite?) 121 assert_equal(-1, BigDecimal.new("-Infinity").infinite?) 122 assert_equal(true, BigDecimal.new("NaN").nan?) 123 assert_equal( 1, BigDecimal.new("1E1111111111111111111").infinite?) 124 end 125 126 def test_new_with_integer 127 assert_equal(BigDecimal("1"), BigDecimal.new(1)) 128 assert_equal(BigDecimal("-1"), BigDecimal.new(-1)) 129 assert_equal(BigDecimal((2**100).to_s), BigDecimal.new(2**100)) 130 assert_equal(BigDecimal((-2**100).to_s), BigDecimal.new(-2**100)) 131 end 132 133 def test_new_with_rational 134 assert_equal(BigDecimal("0.333333333333333333333"), BigDecimal.new(1.quo(3), 21)) 135 assert_equal(BigDecimal("-0.333333333333333333333"), BigDecimal.new(-1.quo(3), 21)) 136 assert_raise(ArgumentError) { BigDecimal.new(1.quo(3)) } 137 end 138 139 def test_new_with_float 140 assert_equal(BigDecimal("0.1235"), BigDecimal(0.1234567, 4)) 141 assert_equal(BigDecimal("-0.1235"), BigDecimal(-0.1234567, 4)) 142 assert_raise(ArgumentError) { BigDecimal.new(0.1) } 143 assert_raise(ArgumentError) { BigDecimal.new(0.1, Float::DIG + 2) } 144 assert_nothing_raised { BigDecimal.new(0.1, Float::DIG + 1) } 145 end 146 147 def test_new_with_big_decimal 148 assert_equal(BigDecimal(1), BigDecimal.new(BigDecimal(1))) 149 assert_equal(BigDecimal('+0'), BigDecimal.new(BigDecimal('+0'))) 150 assert_equal(BigDecimal('-0'), BigDecimal.new(BigDecimal('-0'))) 151 BigDecimal.save_exception_mode do 152 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 153 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 154 assert_positive_infinite(BigDecimal.new(BigDecimal('Infinity'))) 155 assert_negative_infinite(BigDecimal.new(BigDecimal('-Infinity'))) 156 assert_nan(BigDecimal(BigDecimal.new('NaN'))) 157 end 158 end 159 160 def test_new_with_tainted_string 161 Thread.new { 162 $SAFE = 1 163 BigDecimal.new('1'.taint) 164 }.join 165 end 166 167 def _test_mode(type) 168 BigDecimal.mode(type, true) 169 assert_raise(FloatDomainError) { yield } 170 171 BigDecimal.mode(type, false) 172 assert_nothing_raised { yield } 173 end 174 175 def test_mode 176 assert_raise(ArgumentError) { BigDecimal.mode(BigDecimal::EXCEPTION_ALL, 1) } 177 assert_raise(ArgumentError) { BigDecimal.mode(BigDecimal::ROUND_MODE, 256) } 178 assert_raise(ArgumentError) { BigDecimal.mode(BigDecimal::ROUND_MODE, :xyzzy) } 179 assert_raise(TypeError) { BigDecimal.mode(0xf000, true) } 180 181 begin 182 saved_mode = BigDecimal.mode(BigDecimal::ROUND_MODE) 183 184 [ BigDecimal::ROUND_UP, 185 BigDecimal::ROUND_DOWN, 186 BigDecimal::ROUND_HALF_UP, 187 BigDecimal::ROUND_HALF_DOWN, 188 BigDecimal::ROUND_CEILING, 189 BigDecimal::ROUND_FLOOR, 190 BigDecimal::ROUND_HALF_EVEN, 191 ].each do |mode| 192 BigDecimal.mode(BigDecimal::ROUND_MODE, mode) 193 assert_equal(mode, BigDecimal.mode(BigDecimal::ROUND_MODE)) 194 end 195 ensure 196 BigDecimal.mode(BigDecimal::ROUND_MODE, saved_mode) 197 end 198 199 BigDecimal.save_rounding_mode do 200 ROUNDING_MODE_MAP.each do |const, sym| 201 BigDecimal.mode(BigDecimal::ROUND_MODE, sym) 202 assert_equal(const, BigDecimal.mode(BigDecimal::ROUND_MODE)) 203 end 204 end 205 end 206 207 def test_thread_local_mode 208 begin 209 saved_mode = BigDecimal.mode(BigDecimal::ROUND_MODE) 210 211 BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_UP) 212 Thread.start { 213 BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN) 214 assert_equal(BigDecimal::ROUND_HALF_EVEN, BigDecimal.mode(BigDecimal::ROUND_MODE)) 215 }.join 216 assert_equal(BigDecimal::ROUND_UP, BigDecimal.mode(BigDecimal::ROUND_MODE)) 217 ensure 218 BigDecimal.mode(BigDecimal::ROUND_MODE, saved_mode) 219 end 220 end 221 222 def test_save_exception_mode 223 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 224 mode = BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW) 225 BigDecimal.save_exception_mode do 226 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true) 227 end 228 assert_equal(mode, BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW)) 229 230 BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR) 231 BigDecimal.save_exception_mode do 232 BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN) 233 end 234 assert_equal(BigDecimal::ROUND_HALF_EVEN, BigDecimal.mode(BigDecimal::ROUND_MODE)) 235 236 assert_equal(42, BigDecimal.save_exception_mode { 42 }) 237 end 238 239 def test_save_rounding_mode 240 BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR) 241 BigDecimal.save_rounding_mode do 242 BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN) 243 end 244 assert_equal(BigDecimal::ROUND_FLOOR, BigDecimal.mode(BigDecimal::ROUND_MODE)) 245 246 assert_equal(42, BigDecimal.save_rounding_mode { 42 }) 247 end 248 249 def test_save_limit 250 begin 251 old = BigDecimal.limit 252 BigDecimal.limit(100) 253 BigDecimal.save_limit do 254 BigDecimal.limit(200) 255 end 256 assert_equal(100, BigDecimal.limit); 257 ensure 258 BigDecimal.limit(old) 259 end 260 261 assert_equal(42, BigDecimal.save_limit { 42 }) 262 end 263 264 def test_exception_nan 265 _test_mode(BigDecimal::EXCEPTION_NaN) { BigDecimal.new("NaN") } 266 end 267 268 def test_exception_infinity 269 _test_mode(BigDecimal::EXCEPTION_INFINITY) { BigDecimal.new("Infinity") } 270 end 271 272 def test_exception_underflow 273 _test_mode(BigDecimal::EXCEPTION_UNDERFLOW) do 274 x = BigDecimal.new("0.1") 275 100.times do 276 x *= x 277 end 278 end 279 end 280 281 def test_exception_overflow 282 _test_mode(BigDecimal::EXCEPTION_OVERFLOW) do 283 x = BigDecimal.new("10") 284 100.times do 285 x *= x 286 end 287 end 288 end 289 290 def test_exception_zerodivide 291 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 292 _test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { 1 / BigDecimal.new("0") } 293 _test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { -1 / BigDecimal.new("0") } 294 end 295 296 def test_round_up 297 n4 = BigDecimal.new("4") # n4 / 9 = 0.44444... 298 n5 = BigDecimal.new("5") # n5 / 9 = 0.55555... 299 n6 = BigDecimal.new("6") # n6 / 9 = 0.66666... 300 m4, m5, m6 = -n4, -n5, -n6 301 n2h = BigDecimal.new("2.5") 302 n3h = BigDecimal.new("3.5") 303 m2h, m3h = -n2h, -n3h 304 305 BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_UP) 306 assert_operator(n4, :<, n4 / 9 * 9) 307 assert_operator(n5, :<, n5 / 9 * 9) 308 assert_operator(n6, :<, n6 / 9 * 9) 309 assert_operator(m4, :>, m4 / 9 * 9) 310 assert_operator(m5, :>, m5 / 9 * 9) 311 assert_operator(m6, :>, m6 / 9 * 9) 312 assert_equal(3, n2h.round) 313 assert_equal(4, n3h.round) 314 assert_equal(-3, m2h.round) 315 assert_equal(-4, m3h.round) 316 317 BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_DOWN) 318 assert_operator(n4, :>, n4 / 9 * 9) 319 assert_operator(n5, :>, n5 / 9 * 9) 320 assert_operator(n6, :>, n6 / 9 * 9) 321 assert_operator(m4, :<, m4 / 9 * 9) 322 assert_operator(m5, :<, m5 / 9 * 9) 323 assert_operator(m6, :<, m6 / 9 * 9) 324 assert_equal(2, n2h.round) 325 assert_equal(3, n3h.round) 326 assert_equal(-2, m2h.round) 327 assert_equal(-3, m3h.round) 328 329 BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP) 330 assert_operator(n4, :>, n4 / 9 * 9) 331 assert_operator(n5, :<, n5 / 9 * 9) 332 assert_operator(n6, :<, n6 / 9 * 9) 333 assert_operator(m4, :<, m4 / 9 * 9) 334 assert_operator(m5, :>, m5 / 9 * 9) 335 assert_operator(m6, :>, m6 / 9 * 9) 336 assert_equal(3, n2h.round) 337 assert_equal(4, n3h.round) 338 assert_equal(-3, m2h.round) 339 assert_equal(-4, m3h.round) 340 341 BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_DOWN) 342 assert_operator(n4, :>, n4 / 9 * 9) 343 assert_operator(n5, :>, n5 / 9 * 9) 344 assert_operator(n6, :<, n6 / 9 * 9) 345 assert_operator(m4, :<, m4 / 9 * 9) 346 assert_operator(m5, :<, m5 / 9 * 9) 347 assert_operator(m6, :>, m6 / 9 * 9) 348 assert_equal(2, n2h.round) 349 assert_equal(3, n3h.round) 350 assert_equal(-2, m2h.round) 351 assert_equal(-3, m3h.round) 352 353 BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN) 354 assert_operator(n4, :>, n4 / 9 * 9) 355 assert_operator(n5, :<, n5 / 9 * 9) 356 assert_operator(n6, :<, n6 / 9 * 9) 357 assert_operator(m4, :<, m4 / 9 * 9) 358 assert_operator(m5, :>, m5 / 9 * 9) 359 assert_operator(m6, :>, m6 / 9 * 9) 360 assert_equal(2, n2h.round) 361 assert_equal(4, n3h.round) 362 assert_equal(-2, m2h.round) 363 assert_equal(-4, m3h.round) 364 365 BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_CEILING) 366 assert_operator(n4, :<, n4 / 9 * 9) 367 assert_operator(n5, :<, n5 / 9 * 9) 368 assert_operator(n6, :<, n6 / 9 * 9) 369 assert_operator(m4, :<, m4 / 9 * 9) 370 assert_operator(m5, :<, m5 / 9 * 9) 371 assert_operator(m6, :<, m6 / 9 * 9) 372 assert_equal(3, n2h.round) 373 assert_equal(4, n3h.round) 374 assert_equal(-2, m2h.round) 375 assert_equal(-3, m3h.round) 376 377 BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR) 378 assert_operator(n4, :>, n4 / 9 * 9) 379 assert_operator(n5, :>, n5 / 9 * 9) 380 assert_operator(n6, :>, n6 / 9 * 9) 381 assert_operator(m4, :>, m4 / 9 * 9) 382 assert_operator(m5, :>, m5 / 9 * 9) 383 assert_operator(m6, :>, m6 / 9 * 9) 384 assert_equal(2, n2h.round) 385 assert_equal(3, n3h.round) 386 assert_equal(-3, m2h.round) 387 assert_equal(-4, m3h.round) 388 end 389 390 def test_zero_p 391 assert_equal(true, BigDecimal.new("0").zero?) 392 assert_equal(false, BigDecimal.new("1").zero?) 393 assert_equal(true, BigDecimal.new("0E200000000000000").zero?) 394 end 395 396 def test_nonzero_p 397 assert_equal(nil, BigDecimal.new("0").nonzero?) 398 assert_equal(BigDecimal.new("1"), BigDecimal.new("1").nonzero?) 399 end 400 401 def test_double_fig 402 assert_kind_of(Integer, BigDecimal.double_fig) 403 end 404 405 def test_cmp 406 n1 = BigDecimal.new("1") 407 n2 = BigDecimal.new("2") 408 assert_equal( 0, n1 <=> n1) 409 assert_equal( 1, n2 <=> n1) 410 assert_equal(-1, n1 <=> n2) 411 assert_operator(n1, :==, n1) 412 assert_operator(n1, :!=, n2) 413 assert_operator(n1, :<, n2) 414 assert_operator(n1, :<=, n1) 415 assert_operator(n1, :<=, n2) 416 assert_operator(n2, :>, n1) 417 assert_operator(n2, :>=, n1) 418 assert_operator(n1, :>=, n1) 419 420 assert_operator(BigDecimal.new("-0"), :==, BigDecimal.new("0")) 421 assert_operator(BigDecimal.new("0"), :<, BigDecimal.new("1")) 422 assert_operator(BigDecimal.new("1"), :>, BigDecimal.new("0")) 423 assert_operator(BigDecimal.new("1"), :>, BigDecimal.new("-1")) 424 assert_operator(BigDecimal.new("-1"), :<, BigDecimal.new("1")) 425 assert_operator(BigDecimal.new((2**100).to_s), :>, BigDecimal.new("1")) 426 assert_operator(BigDecimal.new("1"), :<, BigDecimal.new((2**100).to_s)) 427 428 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 429 inf = BigDecimal.new("Infinity") 430 assert_operator(inf, :>, 1) 431 assert_operator(1, :<, inf) 432 433 assert_operator(BigDecimal("1E-1"), :==, 10**(-1), '#4825') 434 assert_equal(0, BigDecimal("1E-1") <=> 10**(-1), '#4825') 435 end 436 437 def test_cmp_nan 438 n1 = BigDecimal.new("1") 439 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 440 assert_equal(nil, BigDecimal.new("NaN") <=> n1) 441 assert_equal(false, BigDecimal.new("NaN") > n1) 442 end 443 444 def test_cmp_failing_coercion 445 n1 = BigDecimal.new("1") 446 assert_equal(nil, n1 <=> nil) 447 assert_raise(ArgumentError){n1 > nil} 448 end 449 450 def test_cmp_coerce 451 n1 = BigDecimal.new("1") 452 n2 = BigDecimal.new("2") 453 o1 = Object.new; def o1.coerce(x); [x, BigDecimal.new("1")]; end 454 o2 = Object.new; def o2.coerce(x); [x, BigDecimal.new("2")]; end 455 assert_equal( 0, n1 <=> o1) 456 assert_equal( 1, n2 <=> o1) 457 assert_equal(-1, n1 <=> o2) 458 assert_operator(n1, :==, o1) 459 assert_operator(n1, :!=, o2) 460 assert_operator(n1, :<, o2) 461 assert_operator(n1, :<=, o1) 462 assert_operator(n1, :<=, o2) 463 assert_operator(n2, :>, o1) 464 assert_operator(n2, :>=, o1) 465 assert_operator(n1, :>=, 1) 466 end 467 468 def test_cmp_bignum 469 assert_operator(BigDecimal.new((2**100).to_s), :==, 2**100) 470 end 471 472 def test_cmp_data 473 d = Time.now; def d.coerce(x); [x, x]; end 474 assert_operator(BigDecimal.new((2**100).to_s), :==, d) 475 end 476 477 def test_precs 478 a = BigDecimal.new("1").precs 479 assert_instance_of(Array, a) 480 assert_equal(2, a.size) 481 assert_kind_of(Integer, a[0]) 482 assert_kind_of(Integer, a[1]) 483 end 484 485 def test_hash 486 a = [] 487 b = BigDecimal.new("1") 488 10.times { a << b *= 10 } 489 h = {} 490 a.each_with_index {|x, i| h[x] = i } 491 a.each_with_index do |x, i| 492 assert_equal(i, h[x]) 493 end 494 end 495 496 def test_marshal 497 s = Marshal.dump(BigDecimal("1", 1)) 498 assert_equal(BigDecimal("1", 1), Marshal.load(s)) 499 500 # corrupt data 501 s = s.gsub(/BigDecimal.*\z/m) {|x| x.gsub(/\d/m, "-") } 502 assert_raise(TypeError) { Marshal.load(s) } 503 end 504 505 def test_finite_infinite_nan 506 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 507 BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false) 508 509 x = BigDecimal.new("0") 510 assert_equal(true, x.finite?) 511 assert_equal(nil, x.infinite?) 512 assert_equal(false, x.nan?) 513 y = 1 / x 514 assert_equal(false, y.finite?) 515 assert_equal(1, y.infinite?) 516 assert_equal(false, y.nan?) 517 y = -1 / x 518 assert_equal(false, y.finite?) 519 assert_equal(-1, y.infinite?) 520 assert_equal(false, y.nan?) 521 522 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 523 y = 0 / x 524 assert_equal(false, y.finite?) 525 assert_equal(nil, y.infinite?) 526 assert_equal(true, y.nan?) 527 end 528 529 def test_to_i 530 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 531 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 532 533 x = BigDecimal.new("0") 534 assert_kind_of(Integer, x.to_i) 535 assert_equal(0, x.to_i) 536 assert_raise(FloatDomainError){( 1 / x).to_i} 537 assert_raise(FloatDomainError){(-1 / x).to_i} 538 assert_raise(FloatDomainError) {( 0 / x).to_i} 539 x = BigDecimal.new("1") 540 assert_equal(1, x.to_i) 541 x = BigDecimal.new((2**100).to_s) 542 assert_equal(2**100, x.to_i) 543 end 544 545 def test_to_f 546 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 547 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 548 BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false) 549 550 x = BigDecimal.new("0") 551 assert_instance_of(Float, x.to_f) 552 assert_equal(0.0, x.to_f) 553 assert_equal( 1.0 / 0.0, ( 1 / x).to_f) 554 assert_equal(-1.0 / 0.0, (-1 / x).to_f) 555 assert_equal(true, ( 0 / x).to_f.nan?) 556 x = BigDecimal.new("1") 557 assert_equal(1.0, x.to_f) 558 x = BigDecimal.new((2**100).to_s) 559 assert_equal((2**100).to_f, x.to_f) 560 x = BigDecimal.new("1" + "0" * 10000) 561 assert_equal(0, BigDecimal.new("-0").to_f) 562 563 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true) 564 assert_raise(FloatDomainError) { x.to_f } 565 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 566 assert_kind_of(Float, x .to_f) 567 assert_kind_of(Float, (-x).to_f) 568 569 bug6944 = '[ruby-core:47342]' 570 571 BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, true) 572 x = "1e#{Float::MIN_10_EXP - 2*Float::DIG}" 573 assert_raise(FloatDomainError, x) {BigDecimal(x).to_f} 574 x = "-#{x}" 575 assert_raise(FloatDomainError, x) {BigDecimal(x).to_f} 576 x = "1e#{Float::MIN_10_EXP - Float::DIG}" 577 assert_nothing_raised(FloatDomainError, x) { 578 assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944) 579 } 580 x = "-#{x}" 581 assert_nothing_raised(FloatDomainError, x) { 582 assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944) 583 } 584 585 BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, false) 586 x = "1e#{Float::MIN_10_EXP - 2*Float::DIG}" 587 assert_equal( 0.0, BigDecimal(x).to_f, x) 588 x = "-#{x}" 589 assert_equal(-0.0, BigDecimal(x).to_f, x) 590 x = "1e#{Float::MIN_10_EXP - Float::DIG}" 591 assert_nothing_raised(FloatDomainError, x) { 592 assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944) 593 } 594 x = "-#{x}" 595 assert_nothing_raised(FloatDomainError, x) { 596 assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944) 597 } 598 599 assert_equal( 0.0, BigDecimal( '9e-325').to_f) 600 assert_equal( 0.0, BigDecimal( '10e-325').to_f) 601 assert_equal(-0.0, BigDecimal( '-9e-325').to_f) 602 assert_equal(-0.0, BigDecimal('-10e-325').to_f) 603 end 604 605 def test_coerce 606 a, b = BigDecimal.new("1").coerce(1.0) 607 assert_instance_of(Float, a) 608 assert_instance_of(Float, b) 609 assert_equal(2, 1 + BigDecimal.new("1"), '[ruby-core:25697]') 610 611 a, b = BigDecimal("1").coerce(1.quo(10)) 612 assert_equal(BigDecimal("0.1"), a, '[ruby-core:34318]') 613 614 a, b = BigDecimal("0.11111").coerce(1.quo(3)) 615 assert_equal(BigDecimal("0." + "3"*a.precs[0]), a) 616 617 assert_nothing_raised(TypeError, '#7176') do 618 BigDecimal.new('1') + Rational(1) 619 end 620 end 621 622 def test_uplus 623 x = BigDecimal.new("1") 624 assert_equal(x, x.send(:+@)) 625 end 626 627 def test_add 628 x = BigDecimal.new("1") 629 assert_equal(BigDecimal.new("2"), x + x) 630 assert_equal(1, BigDecimal.new("0") + 1) 631 assert_equal(1, x + 0) 632 633 assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("0") + 0).sign) 634 assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("-0") + 0).sign) 635 assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal.new("-0") + BigDecimal.new("-0")).sign) 636 637 x = BigDecimal.new((2**100).to_s) 638 assert_equal(BigDecimal.new((2**100+1).to_s), x + 1) 639 end 640 641 def test_sub 642 x = BigDecimal.new("1") 643 assert_equal(BigDecimal.new("0"), x - x) 644 assert_equal(-1, BigDecimal.new("0") - 1) 645 assert_equal(1, x - 0) 646 647 assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("0") - 0).sign) 648 assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal.new("-0") - 0).sign) 649 assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("-0") - BigDecimal.new("-0")).sign) 650 651 x = BigDecimal.new((2**100).to_s) 652 assert_equal(BigDecimal.new((2**100-1).to_s), x - 1) 653 end 654 655 def test_sub_with_float 656 assert_kind_of(BigDecimal, BigDecimal.new("3") - 1.0) 657 end 658 659 def test_sub_with_rational 660 assert_kind_of(BigDecimal, BigDecimal.new("3") - 1.quo(3)) 661 end 662 663 def test_mult 664 x = BigDecimal.new((2**100).to_s) 665 assert_equal(BigDecimal.new((2**100 * 3).to_s), (x * 3).to_i) 666 assert_equal(x, (x * 1).to_i) 667 assert_equal(x, (BigDecimal("1") * x).to_i) 668 assert_equal(BigDecimal.new((2**200).to_s), (x * x).to_i) 669 end 670 671 def test_mult_with_float 672 assert_kind_of(BigDecimal, BigDecimal.new("3") * 1.5) 673 end 674 675 def test_mult_with_rational 676 assert_kind_of(BigDecimal, BigDecimal.new("3") * 1.quo(3)) 677 end 678 679 def test_div 680 x = BigDecimal.new((2**100).to_s) 681 assert_equal(BigDecimal.new((2**100 / 3).to_s), (x / 3).to_i) 682 assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("0") / 1).sign) 683 assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal.new("-0") / 1).sign) 684 assert_equal(2, BigDecimal.new("2") / 1) 685 assert_equal(-2, BigDecimal.new("2") / -1) 686 end 687 688 def test_div_with_float 689 assert_kind_of(BigDecimal, BigDecimal.new("3") / 1.5) 690 end 691 692 def test_div_with_rational 693 assert_kind_of(BigDecimal, BigDecimal.new("3") / 1.quo(3)) 694 end 695 696 def test_mod 697 x = BigDecimal.new((2**100).to_s) 698 assert_equal(1, x % 3) 699 assert_equal(2, (-x) % 3) 700 assert_equal(-2, x % -3) 701 assert_equal(-1, (-x) % -3) 702 end 703 704 def test_mod_with_float 705 assert_kind_of(BigDecimal, BigDecimal.new("3") % 1.5) 706 end 707 708 def test_mod_with_rational 709 assert_kind_of(BigDecimal, BigDecimal.new("3") % 1.quo(3)) 710 end 711 712 def test_remainder 713 x = BigDecimal.new((2**100).to_s) 714 assert_equal(1, x.remainder(3)) 715 assert_equal(-1, (-x).remainder(3)) 716 assert_equal(1, x.remainder(-3)) 717 assert_equal(-1, (-x).remainder(-3)) 718 end 719 720 def test_remainder_with_float 721 assert_kind_of(BigDecimal, BigDecimal.new("3").remainder(1.5)) 722 end 723 724 def test_remainder_with_rational 725 assert_kind_of(BigDecimal, BigDecimal.new("3").remainder(1.quo(3))) 726 end 727 728 def test_divmod 729 x = BigDecimal.new((2**100).to_s) 730 assert_equal([(x / 3).floor, 1], x.divmod(3)) 731 assert_equal([(-x / 3).floor, 2], (-x).divmod(3)) 732 733 assert_equal([0, 0], BigDecimal.new("0").divmod(2)) 734 735 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 736 assert_raise(ZeroDivisionError){BigDecimal.new("0").divmod(0)} 737 end 738 739 def test_add_bigdecimal 740 x = BigDecimal.new((2**100).to_s) 741 assert_equal(3000000000000000000000000000000, x.add(x, 1)) 742 assert_equal(2500000000000000000000000000000, x.add(x, 2)) 743 assert_equal(2540000000000000000000000000000, x.add(x, 3)) 744 end 745 746 def test_sub_bigdecimal 747 x = BigDecimal.new((2**100).to_s) 748 assert_equal(1000000000000000000000000000000, x.sub(1, 1)) 749 assert_equal(1300000000000000000000000000000, x.sub(1, 2)) 750 assert_equal(1270000000000000000000000000000, x.sub(1, 3)) 751 end 752 753 def test_mult_bigdecimal 754 x = BigDecimal.new((2**100).to_s) 755 assert_equal(4000000000000000000000000000000, x.mult(3, 1)) 756 assert_equal(3800000000000000000000000000000, x.mult(3, 2)) 757 assert_equal(3800000000000000000000000000000, x.mult(3, 3)) 758 end 759 760 def test_div_bigdecimal 761 x = BigDecimal.new((2**100).to_s) 762 assert_equal(422550200076076467165567735125, x.div(3)) 763 assert_equal(400000000000000000000000000000, x.div(3, 1)) 764 assert_equal(420000000000000000000000000000, x.div(3, 2)) 765 assert_equal(423000000000000000000000000000, x.div(3, 3)) 766 BigDecimal.save_exception_mode do 767 BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) 768 assert_equal(0, BigDecimal("0").div(BigDecimal("Infinity"))) 769 end 770 end 771 772 def test_abs_bigdecimal 773 x = BigDecimal.new((2**100).to_s) 774 assert_equal(1267650600228229401496703205376, x.abs) 775 x = BigDecimal.new("-" + (2**100).to_s) 776 assert_equal(1267650600228229401496703205376, x.abs) 777 x = BigDecimal.new("0") 778 assert_equal(0, x.abs) 779 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 780 x = BigDecimal.new("NaN") 781 assert_equal(true, x.abs.nan?) 782 end 783 784 def test_sqrt_bigdecimal 785 x = BigDecimal.new("0.09") 786 assert_in_delta(0.3, x.sqrt(1), 0.001) 787 x = BigDecimal.new((2**100).to_s) 788 y = BigDecimal("1125899906842624") 789 e = y.exponent 790 assert_equal(true, (x.sqrt(100) - y).abs < BigDecimal("1E#{e-100}")) 791 assert_equal(true, (x.sqrt(200) - y).abs < BigDecimal("1E#{e-200}")) 792 assert_equal(true, (x.sqrt(300) - y).abs < BigDecimal("1E#{e-300}")) 793 x = BigDecimal.new("-" + (2**100).to_s) 794 assert_raise(FloatDomainError) { x.sqrt(1) } 795 x = BigDecimal.new((2**200).to_s) 796 assert_equal(2**100, x.sqrt(1)) 797 798 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 799 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 800 assert_raise(FloatDomainError) { BigDecimal.new("NaN").sqrt(1) } 801 802 assert_equal(0, BigDecimal.new("0").sqrt(1)) 803 assert_equal(1, BigDecimal.new("1").sqrt(1)) 804 end 805 806 def test_fix 807 x = BigDecimal.new("1.1") 808 assert_equal(1, x.fix) 809 end 810 811 def test_frac 812 x = BigDecimal.new("1.1") 813 assert_equal(0.1, x.frac) 814 assert_equal(0.1, BigDecimal.new("0.1").frac) 815 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 816 assert_equal(true, BigDecimal.new("NaN").frac.nan?) 817 end 818 819 def test_round 820 assert_equal(3, BigDecimal.new("3.14159").round) 821 assert_equal(9, BigDecimal.new("8.7").round) 822 assert_equal(3.142, BigDecimal.new("3.14159").round(3)) 823 assert_equal(13300.0, BigDecimal.new("13345.234").round(-2)) 824 825 x = BigDecimal.new("111.111") 826 assert_equal(111 , x.round) 827 assert_equal(111.1 , x.round(1)) 828 assert_equal(111.11 , x.round(2)) 829 assert_equal(111.111, x.round(3)) 830 assert_equal(111.111, x.round(4)) 831 assert_equal(110 , x.round(-1)) 832 assert_equal(100 , x.round(-2)) 833 assert_equal( 0 , x.round(-3)) 834 assert_equal( 0 , x.round(-4)) 835 836 x = BigDecimal.new("2.5") 837 assert_equal(3, x.round(0, BigDecimal::ROUND_UP)) 838 assert_equal(2, x.round(0, BigDecimal::ROUND_DOWN)) 839 assert_equal(3, x.round(0, BigDecimal::ROUND_HALF_UP)) 840 assert_equal(2, x.round(0, BigDecimal::ROUND_HALF_DOWN)) 841 assert_equal(2, x.round(0, BigDecimal::ROUND_HALF_EVEN)) 842 assert_equal(3, x.round(0, BigDecimal::ROUND_CEILING)) 843 assert_equal(2, x.round(0, BigDecimal::ROUND_FLOOR)) 844 assert_raise(ArgumentError) { x.round(0, 256) } 845 846 ROUNDING_MODE_MAP.each do |const, sym| 847 assert_equal(x.round(0, const), x.round(0, sym)) 848 end 849 850 bug3803 = '[ruby-core:32136]' 851 15.times do |n| 852 x = BigDecimal.new("5#{'0'*n}1") 853 assert_equal(10**(n+2), x.round(-(n+2), BigDecimal::ROUND_HALF_DOWN), bug3803) 854 assert_equal(10**(n+2), x.round(-(n+2), BigDecimal::ROUND_HALF_EVEN), bug3803) 855 x = BigDecimal.new("0.5#{'0'*n}1") 856 assert_equal(1, x.round(0, BigDecimal::ROUND_HALF_DOWN), bug3803) 857 assert_equal(1, x.round(0, BigDecimal::ROUND_HALF_EVEN), bug3803) 858 x = BigDecimal.new("-0.5#{'0'*n}1") 859 assert_equal(-1, x.round(0, BigDecimal::ROUND_HALF_DOWN), bug3803) 860 assert_equal(-1, x.round(0, BigDecimal::ROUND_HALF_EVEN), bug3803) 861 end 862 end 863 864 def test_truncate 865 assert_equal(3, BigDecimal.new("3.14159").truncate) 866 assert_equal(8, BigDecimal.new("8.7").truncate) 867 assert_equal(3.141, BigDecimal.new("3.14159").truncate(3)) 868 assert_equal(13300.0, BigDecimal.new("13345.234").truncate(-2)) 869 end 870 871 def test_floor 872 assert_equal(3, BigDecimal.new("3.14159").floor) 873 assert_equal(-10, BigDecimal.new("-9.1").floor) 874 assert_equal(3.141, BigDecimal.new("3.14159").floor(3)) 875 assert_equal(13300.0, BigDecimal.new("13345.234").floor(-2)) 876 end 877 878 def test_ceil 879 assert_equal(4, BigDecimal.new("3.14159").ceil) 880 assert_equal(-9, BigDecimal.new("-9.1").ceil) 881 assert_equal(3.142, BigDecimal.new("3.14159").ceil(3)) 882 assert_equal(13400.0, BigDecimal.new("13345.234").ceil(-2)) 883 end 884 885 def test_to_s 886 assert_equal('-123.45678 90123 45678 9', BigDecimal.new('-123.45678901234567890').to_s('5F')) 887 assert_equal('+123.45678901 23456789', BigDecimal.new('123.45678901234567890').to_s('+8F')) 888 assert_equal(' 123.4567890123456789', BigDecimal.new('123.45678901234567890').to_s(' F')) 889 assert_equal('0.1234567890123456789E3', BigDecimal.new('123.45678901234567890').to_s) 890 assert_equal('0.12345 67890 12345 6789E3', BigDecimal.new('123.45678901234567890').to_s(5)) 891 end 892 893 def test_split 894 x = BigDecimal.new('-123.45678901234567890') 895 assert_equal([-1, "1234567890123456789", 10, 3], x.split) 896 assert_equal([1, "0", 10, 0], BigDecimal.new("0").split) 897 assert_equal([-1, "0", 10, 0], BigDecimal.new("-0").split) 898 899 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 900 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 901 assert_equal([0, "NaN", 10, 0], BigDecimal.new("NaN").split) 902 assert_equal([1, "Infinity", 10, 0], BigDecimal.new("Infinity").split) 903 assert_equal([-1, "Infinity", 10, 0], BigDecimal.new("-Infinity").split) 904 end 905 906 def test_exponent 907 x = BigDecimal.new('-123.45678901234567890') 908 assert_equal(3, x.exponent) 909 end 910 911 def test_inspect 912 x = BigDecimal.new("1234.5678") 913 prec, maxprec = x.precs 914 assert_match(/^#<BigDecimal:[0-9a-f]+,'0.12345678E4',#{prec}\(#{maxprec}\)>$/, x.inspect) 915 end 916 917 def test_power 918 assert_nothing_raised(TypeError, '[ruby-core:47632]') do 919 1000.times { BigDecimal.new('1001.10')**0.75 } 920 end 921 end 922 923 def test_power_with_nil 924 assert_raise(TypeError) do 925 BigDecimal(3) ** nil 926 end 927 end 928 929 def test_power_of_nan 930 BigDecimal.save_exception_mode do 931 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 932 assert_nan(BigDecimal::NAN ** 0) 933 assert_nan(BigDecimal::NAN ** 1) 934 assert_nan(BigDecimal::NAN ** 42) 935 assert_nan(BigDecimal::NAN ** -42) 936 assert_nan(BigDecimal::NAN ** 42.0) 937 assert_nan(BigDecimal::NAN ** -42.0) 938 assert_nan(BigDecimal::NAN ** BigDecimal(42)) 939 assert_nan(BigDecimal::NAN ** BigDecimal(-42)) 940 assert_nan(BigDecimal::NAN ** BigDecimal::INFINITY) 941 BigDecimal.save_exception_mode do 942 BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) 943 assert_nan(BigDecimal::NAN ** (-BigDecimal::INFINITY)) 944 end 945 end 946 end 947 948 def test_power_with_Bignum 949 BigDecimal.save_exception_mode do 950 BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) 951 assert_equal(0, BigDecimal(0) ** (2**100)) 952 953 assert_positive_infinite(BigDecimal(0) ** -(2**100)) 954 assert_positive_infinite((-BigDecimal(0)) ** -(2**100)) 955 assert_negative_infinite((-BigDecimal(0)) ** -(2**100 + 1)) 956 957 assert_equal(1, BigDecimal(1) ** (2**100)) 958 959 assert_positive_infinite(BigDecimal(3) ** (2**100)) 960 assert_positive_zero(BigDecimal(3) ** (-2**100)) 961 962 assert_negative_infinite(BigDecimal(-3) ** (2**100)) 963 assert_positive_infinite(BigDecimal(-3) ** (2**100 + 1)) 964 assert_negative_zero(BigDecimal(-3) ** (-2**100)) 965 assert_positive_zero(BigDecimal(-3) ** (-2**100 - 1)) 966 967 assert_positive_zero(BigDecimal(0.5, Float::DIG) ** (2**100)) 968 assert_positive_infinite(BigDecimal(0.5, Float::DIG) ** (-2**100)) 969 970 assert_negative_zero(BigDecimal(-0.5, Float::DIG) ** (2**100)) 971 assert_positive_zero(BigDecimal(-0.5, Float::DIG) ** (2**100 - 1)) 972 assert_negative_infinite(BigDecimal(-0.5, Float::DIG) ** (-2**100)) 973 assert_positive_infinite(BigDecimal(-0.5, Float::DIG) ** (-2**100 - 1)) 974 end 975 end 976 977 def test_power_with_BigDecimal 978 assert_nothing_raised do 979 assert_in_delta(3 ** 3, BigDecimal(3) ** BigDecimal(3)) 980 end 981 end 982 983 def test_power_of_finite_with_zero 984 x = BigDecimal(1) 985 assert_equal(1, x ** 0) 986 assert_equal(1, x ** 0.quo(1)) 987 assert_equal(1, x ** 0.0) 988 assert_equal(1, x ** BigDecimal(0)) 989 990 x = BigDecimal(42) 991 assert_equal(1, x ** 0) 992 assert_equal(1, x ** 0.quo(1)) 993 assert_equal(1, x ** 0.0) 994 assert_equal(1, x ** BigDecimal(0)) 995 996 x = BigDecimal(-42) 997 assert_equal(1, x ** 0) 998 assert_equal(1, x ** 0.quo(1)) 999 assert_equal(1, x ** 0.0) 1000 assert_equal(1, x ** BigDecimal(0)) 1001 end 1002 1003 def test_power_of_three 1004 x = BigDecimal(3) 1005 assert_equal(81, x ** 4) 1006 assert_equal(1.quo(81), x ** -4) 1007 assert_in_delta(1.0/81, x ** -4) 1008 end 1009 1010 def test_power_of_zero 1011 zero = BigDecimal(0) 1012 assert_equal(0, zero ** 4) 1013 assert_equal(0, zero ** 4.quo(1)) 1014 assert_equal(0, zero ** 4.0) 1015 assert_equal(0, zero ** BigDecimal(4)) 1016 assert_equal(1, zero ** 0) 1017 assert_equal(1, zero ** 0.quo(1)) 1018 assert_equal(1, zero ** 0.0) 1019 assert_equal(1, zero ** BigDecimal(0)) 1020 BigDecimal.save_exception_mode do 1021 BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) 1022 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 1023 assert_positive_infinite(zero ** -1) 1024 assert_positive_infinite(zero ** -1.quo(1)) 1025 assert_positive_infinite(zero ** -1.0) 1026 assert_positive_infinite(zero ** BigDecimal(-1)) 1027 1028 m_zero = BigDecimal("-0") 1029 assert_negative_infinite(m_zero ** -1) 1030 assert_negative_infinite(m_zero ** -1.quo(1)) 1031 assert_negative_infinite(m_zero ** -1.0) 1032 assert_negative_infinite(m_zero ** BigDecimal(-1)) 1033 assert_positive_infinite(m_zero ** -2) 1034 assert_positive_infinite(m_zero ** -2.quo(1)) 1035 assert_positive_infinite(m_zero ** -2.0) 1036 assert_positive_infinite(m_zero ** BigDecimal(-2)) 1037 end 1038 end 1039 1040 def test_power_of_positive_infinity 1041 BigDecimal.save_exception_mode do 1042 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 1043 assert_positive_infinite(BigDecimal::INFINITY ** 3) 1044 assert_positive_infinite(BigDecimal::INFINITY ** 3.quo(1)) 1045 assert_positive_infinite(BigDecimal::INFINITY ** 3.0) 1046 assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(3)) 1047 assert_positive_infinite(BigDecimal::INFINITY ** 2) 1048 assert_positive_infinite(BigDecimal::INFINITY ** 2.quo(1)) 1049 assert_positive_infinite(BigDecimal::INFINITY ** 2.0) 1050 assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(2)) 1051 assert_positive_infinite(BigDecimal::INFINITY ** 1) 1052 assert_positive_infinite(BigDecimal::INFINITY ** 1.quo(1)) 1053 assert_positive_infinite(BigDecimal::INFINITY ** 1.0) 1054 assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(1)) 1055 assert_equal(1, BigDecimal::INFINITY ** 0) 1056 assert_equal(1, BigDecimal::INFINITY ** 0.quo(1)) 1057 assert_equal(1, BigDecimal::INFINITY ** 0.0) 1058 assert_equal(1, BigDecimal::INFINITY ** BigDecimal(0)) 1059 assert_positive_zero(BigDecimal::INFINITY ** -1) 1060 assert_positive_zero(BigDecimal::INFINITY ** -1.quo(1)) 1061 assert_positive_zero(BigDecimal::INFINITY ** -1.0) 1062 assert_positive_zero(BigDecimal::INFINITY ** BigDecimal(-1)) 1063 assert_positive_zero(BigDecimal::INFINITY ** -2) 1064 assert_positive_zero(BigDecimal::INFINITY ** -2.0) 1065 assert_positive_zero(BigDecimal::INFINITY ** BigDecimal(-2)) 1066 end 1067 end 1068 1069 def test_power_of_negative_infinity 1070 BigDecimal.save_exception_mode do 1071 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 1072 assert_negative_infinite((-BigDecimal::INFINITY) ** 3) 1073 assert_negative_infinite((-BigDecimal::INFINITY) ** 3.quo(1)) 1074 assert_negative_infinite((-BigDecimal::INFINITY) ** 3.0) 1075 assert_negative_infinite((-BigDecimal::INFINITY) ** BigDecimal(3)) 1076 assert_positive_infinite((-BigDecimal::INFINITY) ** 2) 1077 assert_positive_infinite((-BigDecimal::INFINITY) ** 2.quo(1)) 1078 assert_positive_infinite((-BigDecimal::INFINITY) ** 2.0) 1079 assert_positive_infinite((-BigDecimal::INFINITY) ** BigDecimal(2)) 1080 assert_negative_infinite((-BigDecimal::INFINITY) ** 1) 1081 assert_negative_infinite((-BigDecimal::INFINITY) ** 1.quo(1)) 1082 assert_negative_infinite((-BigDecimal::INFINITY) ** 1.0) 1083 assert_negative_infinite((-BigDecimal::INFINITY) ** BigDecimal(1)) 1084 assert_equal(1, (-BigDecimal::INFINITY) ** 0) 1085 assert_equal(1, (-BigDecimal::INFINITY) ** 0.quo(1)) 1086 assert_equal(1, (-BigDecimal::INFINITY) ** 0.0) 1087 assert_equal(1, (-BigDecimal::INFINITY) ** BigDecimal(0)) 1088 assert_negative_zero((-BigDecimal::INFINITY) ** -1) 1089 assert_negative_zero((-BigDecimal::INFINITY) ** -1.quo(1)) 1090 assert_negative_zero((-BigDecimal::INFINITY) ** -1.0) 1091 assert_negative_zero((-BigDecimal::INFINITY) ** BigDecimal(-1)) 1092 assert_positive_zero((-BigDecimal::INFINITY) ** -2) 1093 assert_positive_zero((-BigDecimal::INFINITY) ** -2.quo(1)) 1094 assert_positive_zero((-BigDecimal::INFINITY) ** -2.0) 1095 assert_positive_zero((-BigDecimal::INFINITY) ** BigDecimal(-2)) 1096 end 1097 end 1098 1099 def test_power_without_prec 1100 pi = BigDecimal("3.14159265358979323846264338327950288419716939937511") 1101 e = BigDecimal("2.71828182845904523536028747135266249775724709369996") 1102 pow = BigDecimal("22.4591577183610454734271522045437350275893151339967843873233068") 1103 assert_equal(pow, pi.power(e)) 1104 end 1105 1106 def test_power_with_prec 1107 pi = BigDecimal("3.14159265358979323846264338327950288419716939937511") 1108 e = BigDecimal("2.71828182845904523536028747135266249775724709369996") 1109 pow = BigDecimal("22.459157718361045473") 1110 assert_equal(pow, pi.power(e, 20)) 1111 end 1112 1113 def test_limit 1114 BigDecimal.limit(1) 1115 x = BigDecimal.new("3") 1116 assert_equal(90, x ** 4) # OK? must it be 80? 1117 # 3 * 3 * 3 * 3 = 10 * 3 * 3 = 30 * 3 = 90 ??? 1118 assert_raise(ArgumentError) { BigDecimal.limit(-1) } 1119 end 1120 1121 def test_sign 1122 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 1123 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 1124 BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false) 1125 1126 assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal.new("0").sign) 1127 assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal.new("-0").sign) 1128 assert_equal(BigDecimal::SIGN_POSITIVE_FINITE, BigDecimal.new("1").sign) 1129 assert_equal(BigDecimal::SIGN_NEGATIVE_FINITE, BigDecimal.new("-1").sign) 1130 assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, (BigDecimal.new("1") / 0).sign) 1131 assert_equal(BigDecimal::SIGN_NEGATIVE_INFINITE, (BigDecimal.new("-1") / 0).sign) 1132 assert_equal(BigDecimal::SIGN_NaN, (BigDecimal.new("0") / 0).sign) 1133 end 1134 1135 def test_inf 1136 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 1137 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 1138 inf = BigDecimal.new("Infinity") 1139 1140 assert_equal(inf, inf + inf) 1141 assert_equal(true, (inf + (-inf)).nan?) 1142 assert_equal(true, (inf - inf).nan?) 1143 assert_equal(inf, inf - (-inf)) 1144 assert_equal(inf, inf * inf) 1145 assert_equal(true, (inf / inf).nan?) 1146 1147 assert_equal(inf, inf + 1) 1148 assert_equal(inf, inf - 1) 1149 assert_equal(inf, inf * 1) 1150 assert_equal(true, (inf * 0).nan?) 1151 assert_equal(inf, inf / 1) 1152 1153 assert_equal(inf, 1 + inf) 1154 assert_equal(-inf, 1 - inf) 1155 assert_equal(inf, 1 * inf) 1156 assert_equal(-inf, -1 * inf) 1157 assert_equal(true, (0 * inf).nan?) 1158 assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (1 / inf).sign) 1159 assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (-1 / inf).sign) 1160 end 1161 1162 def test_to_special_string 1163 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 1164 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 1165 nan = BigDecimal.new("NaN") 1166 assert_equal("NaN", nan.to_s) 1167 inf = BigDecimal.new("Infinity") 1168 assert_equal("Infinity", inf.to_s) 1169 assert_equal(" Infinity", inf.to_s(" ")) 1170 assert_equal("+Infinity", inf.to_s("+")) 1171 assert_equal("-Infinity", (-inf).to_s) 1172 pzero = BigDecimal.new("0") 1173 assert_equal("0.0", pzero.to_s) 1174 assert_equal(" 0.0", pzero.to_s(" ")) 1175 assert_equal("+0.0", pzero.to_s("+")) 1176 assert_equal("-0.0", (-pzero).to_s) 1177 end 1178 1179 def test_to_string 1180 assert_equal("0.01", BigDecimal("0.01").to_s("F")) 1181 s = "0." + "0" * 100 + "1" 1182 assert_equal(s, BigDecimal(s).to_s("F")) 1183 s = "1" + "0" * 100 + ".0" 1184 assert_equal(s, BigDecimal(s).to_s("F")) 1185 end 1186 1187 def test_ctov 1188 assert_equal(0.1, BigDecimal.new("1E-1")) 1189 assert_equal(10, BigDecimal.new("1E+1")) 1190 assert_equal(1, BigDecimal.new("+1")) 1191 BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) 1192 1193 assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, BigDecimal.new("1E1" + "0" * 10000).sign) 1194 assert_equal(BigDecimal::SIGN_NEGATIVE_INFINITE, BigDecimal.new("-1E1" + "0" * 10000).sign) 1195 assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal.new("1E-1" + "0" * 10000).sign) 1196 assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal.new("-1E-1" + "0" * 10000).sign) 1197 end 1198 1199 def test_split_under_gc_stress 1200 bug3258 = '[ruby-dev:41213]' 1201 expect = 10.upto(20).map{|i|[1, "1", 10, i+1].inspect} 1202 assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, expect, [], bug3258) 1203 GC.stress = true 1204 10.upto(20) do |i| 1205 p BigDecimal.new("1"+"0"*i).split 1206 end 1207 EOS 1208 end 1209 1210 def test_coerce_under_gc_stress 1211 assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], []) 1212 expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal" 1213 b = BigDecimal.new("1") 1214 GC.stress = true 1215 10.times do 1216 begin 1217 b.coerce(:too_long_to_embed_as_string) 1218 rescue => e 1219 raise unless e.is_a?(TypeError) 1220 raise "'\#{expect}' is expected, but '\#{e.message}'" unless e.message == expect 1221 end 1222 end 1223 EOS 1224 end 1225 1226 def test_INFINITY 1227 assert(BigDecimal::INFINITY.infinite?, "BigDecimal::INFINITY is not a infinity") 1228 end 1229 1230 def test_NAN 1231 assert(BigDecimal::NAN.nan?, "BigDecimal::NAN is not NaN") 1232 end 1233 1234 def test_exp_with_zerp_precision 1235 assert_raise(ArgumentError) do 1236 BigMath.exp(1, 0) 1237 end 1238 end 1239 1240 def test_exp_with_negative_precision 1241 assert_raise(ArgumentError) do 1242 BigMath.exp(1, -42) 1243 end 1244 end 1245 1246 def test_exp_with_complex 1247 assert_raise(ArgumentError) do 1248 BigMath.exp(Complex(1, 2), 20) 1249 end 1250 end 1251 1252 def test_exp_with_negative_infinite 1253 BigDecimal.save_exception_mode do 1254 BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) 1255 assert_equal(0, BigMath.exp(-BigDecimal::INFINITY, 20)) 1256 end 1257 end 1258 1259 def test_exp_with_positive_infinite 1260 BigDecimal.save_exception_mode do 1261 BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) 1262 assert(BigMath.exp(BigDecimal::INFINITY, 20) > 0) 1263 assert(BigMath.exp(BigDecimal::INFINITY, 20).infinite?) 1264 end 1265 end 1266 1267 def test_exp_with_nan 1268 BigDecimal.save_exception_mode do 1269 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 1270 assert(BigMath.exp(BigDecimal::NAN, 20).nan?) 1271 end 1272 end 1273 1274 def test_exp_with_1 1275 assert_in_epsilon(Math::E, BigMath.exp(1, 20)) 1276 end 1277 1278 def test_BigMath_exp 1279 prec = 20 1280 assert_in_epsilon(Math.exp(20), BigMath.exp(BigDecimal("20"), prec)) 1281 assert_in_epsilon(Math.exp(40), BigMath.exp(BigDecimal("40"), prec)) 1282 assert_in_epsilon(Math.exp(-20), BigMath.exp(BigDecimal("-20"), prec)) 1283 assert_in_epsilon(Math.exp(-40), BigMath.exp(BigDecimal("-40"), prec)) 1284 end 1285 1286 def test_BigMath_exp_with_float 1287 prec = 20 1288 assert_in_epsilon(Math.exp(20), BigMath.exp(20.0, prec)) 1289 assert_in_epsilon(Math.exp(40), BigMath.exp(40.0, prec)) 1290 assert_in_epsilon(Math.exp(-20), BigMath.exp(-20.0, prec)) 1291 assert_in_epsilon(Math.exp(-40), BigMath.exp(-40.0, prec)) 1292 end 1293 1294 def test_BigMath_exp_with_fixnum 1295 prec = 20 1296 assert_in_epsilon(Math.exp(20), BigMath.exp(20, prec)) 1297 assert_in_epsilon(Math.exp(40), BigMath.exp(40, prec)) 1298 assert_in_epsilon(Math.exp(-20), BigMath.exp(-20, prec)) 1299 assert_in_epsilon(Math.exp(-40), BigMath.exp(-40, prec)) 1300 end 1301 1302 def test_BigMath_exp_with_rational 1303 prec = 20 1304 assert_in_epsilon(Math.exp(20), BigMath.exp(Rational(40,2), prec)) 1305 assert_in_epsilon(Math.exp(40), BigMath.exp(Rational(80,2), prec)) 1306 assert_in_epsilon(Math.exp(-20), BigMath.exp(Rational(-40,2), prec)) 1307 assert_in_epsilon(Math.exp(-40), BigMath.exp(Rational(-80,2), prec)) 1308 end 1309 1310 def test_BigMath_exp_under_gc_stress 1311 assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], []) 1312 expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal" 1313 10.times do 1314 begin 1315 BigMath.exp(:too_long_to_embed_as_string, 6) 1316 rescue => e 1317 raise unless e.is_a?(ArgumentError) 1318 raise "'\#{expect}' is expected, but '\#{e.message}'" unless e.message == expect 1319 end 1320 end 1321 EOS 1322 end 1323 1324 def test_BigMath_log_with_nil 1325 assert_raise(ArgumentError) do 1326 BigMath.log(nil, 20) 1327 end 1328 end 1329 1330 def test_BigMath_log_with_nil_precision 1331 assert_raise(ArgumentError) do 1332 BigMath.log(1, nil) 1333 end 1334 end 1335 1336 def test_BigMath_log_with_complex 1337 assert_raise(Math::DomainError) do 1338 BigMath.log(Complex(1, 2), 20) 1339 end 1340 end 1341 1342 def test_BigMath_log_with_zerp_precision 1343 assert_raise(ArgumentError) do 1344 BigMath.log(1, 0) 1345 end 1346 end 1347 1348 def test_BigMath_log_with_negative_precision 1349 assert_raise(ArgumentError) do 1350 BigMath.log(1, -42) 1351 end 1352 end 1353 1354 def test_BigMath_log_with_negative_infinite 1355 BigDecimal.save_exception_mode do 1356 BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) 1357 assert_raise(Math::DomainError) do 1358 BigMath.log(-BigDecimal::INFINITY, 20) 1359 end 1360 end 1361 end 1362 1363 def test_BigMath_log_with_positive_infinite 1364 BigDecimal.save_exception_mode do 1365 BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) 1366 assert(BigMath.log(BigDecimal::INFINITY, 20) > 0) 1367 assert(BigMath.log(BigDecimal::INFINITY, 20).infinite?) 1368 end 1369 end 1370 1371 def test_BigMath_log_with_nan 1372 BigDecimal.save_exception_mode do 1373 BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) 1374 assert(BigMath.log(BigDecimal::NAN, 20).nan?) 1375 end 1376 end 1377 1378 def test_BigMath_log_with_1 1379 assert_in_delta(0.0, BigMath.log(1, 20)) 1380 assert_in_delta(0.0, BigMath.log(1.0, 20)) 1381 assert_in_delta(0.0, BigMath.log(BigDecimal(1), 20)) 1382 end 1383 1384 def test_BigMath_log_with_exp_1 1385 assert_in_delta(1.0, BigMath.log(BigMath.exp(1, 20), 20)) 1386 end 1387 1388 def test_BigMath_log_with_2 1389 assert_in_delta(Math.log(2), BigMath.log(2, 20)) 1390 assert_in_delta(Math.log(2), BigMath.log(2.0, 20)) 1391 assert_in_delta(Math.log(2), BigMath.log(BigDecimal(2), 20)) 1392 end 1393 1394 def test_BigMath_log_with_square_of_exp_2 1395 assert_in_delta(2, BigMath.log(BigMath.exp(1, 20)**2, 20)) 1396 end 1397 1398 def test_BigMath_log_with_42 1399 assert_in_delta(Math.log(42), BigMath.log(42, 20)) 1400 assert_in_delta(Math.log(42), BigMath.log(42.0, 20)) 1401 assert_in_delta(Math.log(42), BigMath.log(BigDecimal(42), 20)) 1402 end 1403 1404 def test_BigMath_log_with_reciprocal_of_42 1405 assert_in_delta(Math.log(1e-42), BigMath.log(1e-42, 20)) 1406 assert_in_delta(Math.log(1e-42), BigMath.log(BigDecimal("1e-42"), 20)) 1407 end 1408 1409 def test_BigMath_log_under_gc_stress 1410 assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], []) 1411 expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal" 1412 10.times do 1413 begin 1414 BigMath.log(:too_long_to_embed_as_string, 6) 1415 rescue => e 1416 raise unless e.is_a?(ArgumentError) 1417 raise "'\#{expect}' is expected, but '\#{e.message}'" unless e.message == expect 1418 end 1419 end 1420 EOS 1421 end 1422 1423 def test_dup 1424 [1, -1, 2**100, -2**100].each do |i| 1425 x = BigDecimal(i) 1426 assert_equal(x, x.dup) 1427 end 1428 end 1429 1430 def test_dup_subclass 1431 c = Class.new(BigDecimal) 1432 x = c.new(1) 1433 y = x.dup 1434 assert_equal(1, y) 1435 assert_kind_of(c, y) 1436 end 1437 1438 def test_to_d 1439 bug6093 = '[ruby-core:42969]' 1440 code = "exit(BigDecimal.new('10.0') == 10.0.to_d)" 1441 assert_ruby_status(%w[-rbigdecimal -rbigdecimal/util -rmathn -], code, bug6093) 1442 end 1443 1444 def test_bug6406 1445 assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], []) 1446 Thread.current.keys.to_s 1447 EOS 1448 end 1449end 1450