mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* ext/bigdecimal/bigdecimal.c (VpSetPTR): fix for limitation of the resulting
precision. * test/bigdecimal/test_bigdecimal.rb (test_limit): add tests for the above change. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44153 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									7d3538db3f
								
							
						
					
					
						commit
						df33325192
					
				
					 3 changed files with 41 additions and 2 deletions
				
			
		|  | @ -1,3 +1,11 @@ | ||||||
|  | Wed Dec 13 02:00:00 2013  Kenta Murata  <mrkn@mrkn.jp> | ||||||
|  | 
 | ||||||
|  | 	* ext/bigdecimal/bigdecimal.c (VpSetPTR): fix for limitation of the resulting | ||||||
|  | 	  precision. | ||||||
|  | 
 | ||||||
|  | 	* test/bigdecimal/test_bigdecimal.rb (test_limit): add tests for the above | ||||||
|  | 	  change. | ||||||
|  | 
 | ||||||
| Wed Dec 13 01:56:00 2013  Kenta Murata  <mrkn@mrkn.jp> | Wed Dec 13 01:56:00 2013  Kenta Murata  <mrkn@mrkn.jp> | ||||||
| 
 | 
 | ||||||
| 	* ext/bigdecimal/bigdecimal.c (VpAddAbs): put out a conditional branch from | 	* ext/bigdecimal/bigdecimal.c (VpAddAbs): put out a conditional branch from | ||||||
|  |  | ||||||
|  | @ -4189,6 +4189,7 @@ VpAddAbs(Real *a, Real *b, Real *c) | ||||||
|     a_pos = ap; |     a_pos = ap; | ||||||
|     b_pos = bp; |     b_pos = bp; | ||||||
|     c_pos = cp; |     c_pos = cp; | ||||||
|  | 
 | ||||||
|     if (word_shift == (size_t)-1L) return 0; /* Overflow */ |     if (word_shift == (size_t)-1L) return 0; /* Overflow */ | ||||||
|     if (b_pos == (size_t)-1L) goto Assign_a; |     if (b_pos == (size_t)-1L) goto Assign_a; | ||||||
| 
 | 
 | ||||||
|  | @ -4380,12 +4381,19 @@ static size_t | ||||||
| VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, BDIGIT *av, BDIGIT *bv) | VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, BDIGIT *av, BDIGIT *bv) | ||||||
| { | { | ||||||
|     size_t left_word, right_word, word_shift; |     size_t left_word, right_word, word_shift; | ||||||
|  | 
 | ||||||
|  |     size_t const round_limit = (VpGetPrecLimit() + BASE_FIG - 1) / BASE_FIG; | ||||||
|  | 
 | ||||||
|  |     assert(a->exponent >= b->expoennt); | ||||||
|  | 
 | ||||||
|     c->frac[0] = 0; |     c->frac[0] = 0; | ||||||
|     *av = *bv = 0; |     *av = *bv = 0; | ||||||
|  | 
 | ||||||
|     word_shift = (a->exponent - b->exponent); |     word_shift = (a->exponent - b->exponent); | ||||||
|     left_word = b->Prec + word_shift; |     left_word = b->Prec + word_shift; | ||||||
|     right_word = Max(a->Prec, left_word); |     right_word = Max(a->Prec, left_word); | ||||||
|     left_word = c->MaxPrec - 1;    /* -1 ... prepare for round up */ |     left_word = c->MaxPrec - 1;    /* -1 ... prepare for round up */ | ||||||
|  | 
 | ||||||
|     /*
 |     /*
 | ||||||
|      * check if 'round' is needed. |      * check if 'round' is needed. | ||||||
|      */ |      */ | ||||||
|  | @ -4408,7 +4416,9 @@ VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, | ||||||
| 	     *   a_pos =    | | 	     *   a_pos =    | | ||||||
| 	     */ | 	     */ | ||||||
| 	    *a_pos = left_word; | 	    *a_pos = left_word; | ||||||
| 	    *av = a->frac[*a_pos];    /* av is 'A' shown in above. */ | 	    if (*a_pos <= round_limit) { | ||||||
|  | 		*av = a->frac[*a_pos];    /* av is 'A' shown in above. */ | ||||||
|  | 	    } | ||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
| 	    /*
 | 	    /*
 | ||||||
|  | @ -4427,7 +4437,9 @@ VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, | ||||||
| 	     */ | 	     */ | ||||||
| 	    if (c->MaxPrec >= word_shift + 1) { | 	    if (c->MaxPrec >= word_shift + 1) { | ||||||
| 		*b_pos = c->MaxPrec - word_shift - 1; | 		*b_pos = c->MaxPrec - word_shift - 1; | ||||||
| 		*bv = b->frac[*b_pos]; | 		if (*b_pos + word_shift <= round_limit) { | ||||||
|  | 		    *bv = b->frac[*b_pos]; | ||||||
|  | 		} | ||||||
| 	    } | 	    } | ||||||
| 	    else { | 	    else { | ||||||
| 		*b_pos = -1L; | 		*b_pos = -1L; | ||||||
|  |  | ||||||
|  | @ -1151,6 +1151,25 @@ class TestBigDecimal < Test::Unit::TestCase | ||||||
|     assert_equal(90, x ** 4) # OK? must it be 80? |     assert_equal(90, x ** 4) # OK? must it be 80? | ||||||
|     # 3 * 3 * 3 * 3 = 10 * 3 * 3 = 30 * 3 = 90 ??? |     # 3 * 3 * 3 * 3 = 10 * 3 * 3 = 30 * 3 = 90 ??? | ||||||
|     assert_raise(ArgumentError) { BigDecimal.limit(-1) } |     assert_raise(ArgumentError) { BigDecimal.limit(-1) } | ||||||
|  | 
 | ||||||
|  |     bug7458 = '[ruby-core:50269] [#7458]' | ||||||
|  |     one = BigDecimal('1') | ||||||
|  |     epsilon = BigDecimal('0.7E-18') | ||||||
|  |     BigDecimal.save_limit do | ||||||
|  |       BigDecimal.limit(0) | ||||||
|  |       assert_equal(BigDecimal("1.0000000000000000007"), one + epsilon, "limit(0) #{bug7458}") | ||||||
|  | 
 | ||||||
|  |       1.upto(18) do |lim| | ||||||
|  |         BigDecimal.limit(lim) | ||||||
|  |         assert_equal(BigDecimal("1.0"), one + epsilon, "limit(#{lim}) #{bug7458}") | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       BigDecimal.limit(19) | ||||||
|  |       assert_equal(BigDecimal("1.000000000000000001"), one + epsilon, "limit(19) #{bug7458}") | ||||||
|  | 
 | ||||||
|  |       BigDecimal.limit(20) | ||||||
|  |       assert_equal(BigDecimal("1.0000000000000000007"), one + epsilon, "limit(20) #{bug7458}") | ||||||
|  |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_sign |   def test_sign | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 mrkn
						mrkn