@@ -15,6 +15,8 @@ class TestBigDecimal < Test::Unit::TestCase
1515 LLONG_MIN = [ LLONG_MAX + 1 ] . pack ( "Q!" ) . unpack ( "q!" ) [ 0 ]
1616 ULLONG_MAX = ( 1 << Fiddle ::SIZEOF_LONG_LONG *8 ) - 1
1717 LIMITS = {
18+ "LONG_MAX" => LONG_MAX ,
19+ "LONG_MIN" => LONG_MIN ,
1820 "LLONG_MIN" => LLONG_MIN ,
1921 "ULLONG_MAX" => ULLONG_MAX ,
2022 "FIXNUM_MIN" => LONG_MIN / 2 ,
@@ -25,6 +27,9 @@ class TestBigDecimal < Test::Unit::TestCase
2527 } . freeze
2628 end
2729
30+ EXPONENT_MAX = LIMITS [ 'LONG_MAX' ] / BASE_FIG * BASE_FIG
31+ EXPONENT_MIN = ( LIMITS [ 'LONG_MIN' ] - 2 ) / BASE_FIG * BASE_FIG + BASE_FIG + 1
32+
2833 ROUNDING_MODE_MAP = [
2934 [ BigDecimal ::ROUND_UP , :up ] ,
3035 [ BigDecimal ::ROUND_DOWN , :down ] ,
@@ -80,12 +85,24 @@ def test_BigDecimal
8085 assert_raise ( ArgumentError ) { BigDecimal ( "1" , -1 ) }
8186 assert_raise_with_message ( ArgumentError , /"1__1_1"/ ) { BigDecimal ( "1__1_1" ) }
8287 assert_raise_with_message ( ArgumentError , /"_1_1_1"/ ) { BigDecimal ( "_1_1_1" ) }
88+ assert ( BigDecimal ( "0.1E#{ EXPONENT_MAX } " ) . finite? )
89+ assert ( BigDecimal ( "0.1E#{ EXPONENT_MIN } " ) . finite? )
8390
8491 BigDecimal . save_exception_mode do
8592 BigDecimal . mode ( BigDecimal ::EXCEPTION_OVERFLOW , false )
93+ BigDecimal . mode ( BigDecimal ::EXCEPTION_UNDERFLOW , false )
8694 BigDecimal . mode ( BigDecimal ::EXCEPTION_NaN , false )
8795 assert_positive_infinite ( BigDecimal ( "Infinity" ) )
88- assert_positive_infinite ( BigDecimal ( "1E1111111111111111111" ) )
96+ assert_positive_infinite ( BigDecimal ( "0.1E#{ EXPONENT_MAX + 1 } " ) )
97+ assert_negative_infinite ( BigDecimal ( "-0.1E#{ EXPONENT_MAX + 1 } " ) )
98+ assert_positive_infinite ( BigDecimal ( "1E#{ EXPONENT_MAX } " ) )
99+ assert_negative_infinite ( BigDecimal ( "-1E#{ EXPONENT_MAX } " ) )
100+ assert_positive_zero ( BigDecimal ( "0E#{ EXPONENT_MAX + 1 } " ) )
101+ assert_negative_zero ( BigDecimal ( "-0E#{ EXPONENT_MAX + 1 } " ) )
102+ assert_positive_zero ( BigDecimal ( "0.1E#{ EXPONENT_MIN - 1 } " ) )
103+ assert_negative_zero ( BigDecimal ( "-0.1E#{ EXPONENT_MIN - 1 } " ) )
104+ assert_positive_zero ( BigDecimal ( "0.01E#{ EXPONENT_MIN } " ) )
105+ assert_negative_zero ( BigDecimal ( "-0.01E#{ EXPONENT_MIN } " ) )
89106 assert_positive_infinite ( BigDecimal ( " \t \n \r \r Infinity \t \n \r \r " ) )
90107 assert_negative_infinite ( BigDecimal ( "-Infinity" ) )
91108 assert_negative_infinite ( BigDecimal ( " \t \n \r \r -Infinity \t \n \r \r " ) )
@@ -460,39 +477,48 @@ def test_exception_overflow
460477 end
461478 end
462479
480+ def test_add_sub_underflow
481+ BigDecimal . mode ( BigDecimal ::EXCEPTION_UNDERFLOW , false )
482+ x = BigDecimal ( "0.100000000002E#{ EXPONENT_MIN + 10 } " )
483+ y = BigDecimal ( "0.100000000001E#{ EXPONENT_MIN + 10 } " )
484+ z = BigDecimal ( "0.101E#{ EXPONENT_MIN + 10 } " )
485+ assert_not_equal ( 0 , x - z )
486+ assert_not_equal ( 0 , z - y )
487+ assert_positive_zero ( x + ( -y ) )
488+ assert_positive_zero ( x - y )
489+ assert_positive_zero ( ( -y ) - ( -x ) )
490+ assert_negative_zero ( ( -x ) + y )
491+ assert_negative_zero ( y - x )
492+ assert_negative_zero ( ( -x ) - ( -y ) )
493+ end
494+
463495 def test_mult_div_overflow_underflow_sign
464496 BigDecimal . mode ( BigDecimal ::EXCEPTION_OVERFLOW , false )
465497 BigDecimal . mode ( BigDecimal ::EXCEPTION_UNDERFLOW , false )
498+ large_x = BigDecimal ( "0.1E#{ EXPONENT_MAX } " )
499+ small_x = BigDecimal ( "0.1E#{ EXPONENT_MIN } " )
466500
467- large_x = BigDecimal ( "10" )
468- 100 . times do
469- x2 = large_x * large_x
470- break if x2 . infinite?
471- large_x = x2
472- end
473-
474- small_x = BigDecimal ( "0.1" )
475- 100 . times do
476- x2 = small_x * small_x
477- break if x2 . zero?
478- small_x = x2
479- end
480-
501+ assert_positive_infinite ( large_x * 10 )
502+ assert_positive_infinite ( 10 * large_x )
481503 assert_positive_infinite ( large_x * large_x )
482504 assert_negative_infinite ( large_x * ( -large_x ) )
483505 assert_negative_infinite ( ( -large_x ) * large_x )
484506 assert_positive_infinite ( ( -large_x ) * ( -large_x ) )
485507
508+ assert_positive_zero ( small_x * 0.1 )
509+ assert_positive_zero ( 0.1 * small_x )
486510 assert_positive_zero ( small_x * small_x )
487511 assert_negative_zero ( small_x * ( -small_x ) )
488512 assert_negative_zero ( ( -small_x ) * small_x )
489513 assert_positive_zero ( ( -small_x ) * ( -small_x ) )
490514
515+ assert_positive_infinite ( large_x . div ( 0.1 , 10 ) )
491516 assert_positive_infinite ( large_x . div ( small_x , 10 ) )
492517 assert_negative_infinite ( large_x . div ( -small_x , 10 ) )
493518 assert_negative_infinite ( ( -large_x ) . div ( small_x , 10 ) )
494519 assert_positive_infinite ( ( -large_x ) . div ( -small_x , 10 ) )
495520
521+ assert_positive_zero ( small_x . div ( 10 , 10 ) )
496522 assert_positive_zero ( small_x . div ( large_x , 10 ) )
497523 assert_negative_zero ( small_x . div ( -large_x , 10 ) )
498524 assert_negative_zero ( ( -small_x ) . div ( large_x , 10 ) )
0 commit comments