mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	Import bigdecimal 2.0.2 (#3905)
* remove duplicated include * Make BigDecimal#round with argument < 1 return Integer Fixes [Bug #12780] * Use a higher default precision for BigDecimal#power and #** When a fractional power is given, increase the precision if the precision isn't specified via power's second argument: Float: increase by 15 (rough number of decimal precision in float) BigDecimal: increase by adding similar precision modifier as done to calculate the base precision. Rational: double the precision, since a BigDecimal is created, but the created BigDecimal uses the same precision. Increasing the precision for these power calculations has the obvious tradeoff of making the calculations slower. Fixes Ruby Bug #17264 * Use DBLE_FIG for a Float value * Version 2.0.1 Co-authored-by: pavel <pavel.rosicky@easy.cz> Co-authored-by: Jeremy Evans <code@jeremyevans.net>
This commit is contained in:
		
							parent
							
								
									9d85ed6cbb
								
							
						
					
					
						commit
						a86c147579
					
				
				
				Notes:
				
					git
				
				2020-12-15 15:17:40 +09:00 
				
			
			Merged-By: mrkn <mrkn@ruby-lang.org>
					 3 changed files with 29 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -25,7 +25,6 @@
 | 
			
		|||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include "math.h"
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_IEEEFP_H
 | 
			
		||||
#include <ieeefp.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -1792,10 +1791,10 @@ BigDecimal_fix(VALUE self)
 | 
			
		|||
 * more than that many digits.
 | 
			
		||||
 *
 | 
			
		||||
 * If n is specified and negative, at least that many digits to the left of the
 | 
			
		||||
 * decimal point will be 0 in the result.
 | 
			
		||||
 * decimal point will be 0 in the result, and return value will be an Integer.
 | 
			
		||||
 *
 | 
			
		||||
 *	BigDecimal('3.14159').round(3) #=> 3.142
 | 
			
		||||
 *	BigDecimal('13345.234').round(-2) #=> 13300.0
 | 
			
		||||
 *	BigDecimal('13345.234').round(-2) #=> 13300
 | 
			
		||||
 *
 | 
			
		||||
 * The value of the optional mode argument can be used to determine how
 | 
			
		||||
 * rounding is performed; see BigDecimal.mode.
 | 
			
		||||
| 
						 | 
				
			
			@ -1808,6 +1807,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
 | 
			
		|||
    int    iLoc = 0;
 | 
			
		||||
    VALUE  vLoc;
 | 
			
		||||
    VALUE  vRound;
 | 
			
		||||
    int    round_to_int = 0;
 | 
			
		||||
    size_t mx, pl;
 | 
			
		||||
 | 
			
		||||
    unsigned short sw = VpGetRoundMode();
 | 
			
		||||
| 
						 | 
				
			
			@ -1815,6 +1815,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
 | 
			
		|||
    switch (rb_scan_args(argc, argv, "02", &vLoc, &vRound)) {
 | 
			
		||||
      case 0:
 | 
			
		||||
	iLoc = 0;
 | 
			
		||||
        round_to_int = 1;
 | 
			
		||||
	break;
 | 
			
		||||
      case 1:
 | 
			
		||||
        if (RB_TYPE_P(vLoc, T_HASH)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1822,6 +1823,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
 | 
			
		|||
	}
 | 
			
		||||
	else {
 | 
			
		||||
	    iLoc = NUM2INT(vLoc);
 | 
			
		||||
            if (iLoc < 1) round_to_int = 1;
 | 
			
		||||
	}
 | 
			
		||||
	break;
 | 
			
		||||
      case 2:
 | 
			
		||||
| 
						 | 
				
			
			@ -1843,7 +1845,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
 | 
			
		|||
    GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
 | 
			
		||||
    VpSetPrecLimit(pl);
 | 
			
		||||
    VpActiveRound(c, a, sw, iLoc);
 | 
			
		||||
    if (argc == 0) {
 | 
			
		||||
    if (round_to_int) {
 | 
			
		||||
	return BigDecimal_to_i(ToValue(c));
 | 
			
		||||
    }
 | 
			
		||||
    return ToValue(c);
 | 
			
		||||
| 
						 | 
				
			
			@ -2363,7 +2365,10 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
 | 
			
		|||
	    }
 | 
			
		||||
	    goto retry;
 | 
			
		||||
	}
 | 
			
		||||
	exp = GetVpValueWithPrec(vexp, DBL_DIG+1, 1);
 | 
			
		||||
        if (NIL_P(prec)) {
 | 
			
		||||
            n += DBLE_FIG;
 | 
			
		||||
        }
 | 
			
		||||
        exp = GetVpValueWithPrec(vexp, DBLE_FIG, 1);
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      case T_RATIONAL:
 | 
			
		||||
| 
						 | 
				
			
			@ -2378,6 +2383,9 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
 | 
			
		|||
	    goto retry;
 | 
			
		||||
	}
 | 
			
		||||
	exp = GetVpValueWithPrec(vexp, n, 1);
 | 
			
		||||
        if (NIL_P(prec)) {
 | 
			
		||||
            n += n;
 | 
			
		||||
        }
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      case T_DATA:
 | 
			
		||||
| 
						 | 
				
			
			@ -2388,6 +2396,10 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
 | 
			
		|||
		vexp = BigDecimal_to_i(vexp);
 | 
			
		||||
		goto retry;
 | 
			
		||||
	    }
 | 
			
		||||
            if (NIL_P(prec)) {
 | 
			
		||||
                GUARD_OBJ(y, GetVpValue(vexp, 1));
 | 
			
		||||
                n += y->Prec*VpBaseFig();
 | 
			
		||||
            }
 | 
			
		||||
	    exp = DATA_PTR(vexp);
 | 
			
		||||
	    break;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
# coding: utf-8
 | 
			
		||||
 | 
			
		||||
bigdecimal_version = '2.0.1'
 | 
			
		||||
bigdecimal_version = '2.0.2'
 | 
			
		||||
 | 
			
		||||
Gem::Specification.new do |s|
 | 
			
		||||
  s.name          = "bigdecimal"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1104,6 +1104,11 @@ class TestBigDecimal < Test::Unit::TestCase
 | 
			
		|||
      assert_equal(-1, x.round(0, BigDecimal::ROUND_HALF_DOWN), bug3803)
 | 
			
		||||
      assert_equal(-1, x.round(0, BigDecimal::ROUND_HALF_EVEN), bug3803)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    assert_instance_of(Integer, x.round)
 | 
			
		||||
    assert_instance_of(Integer, x.round(0))
 | 
			
		||||
    assert_instance_of(Integer, x.round(-1))
 | 
			
		||||
    assert_instance_of(BigDecimal, x.round(1))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_round_half_even
 | 
			
		||||
| 
						 | 
				
			
			@ -1456,8 +1461,13 @@ class TestBigDecimal < Test::Unit::TestCase
 | 
			
		|||
  def test_power_without_prec
 | 
			
		||||
    pi  = BigDecimal("3.14159265358979323846264338327950288419716939937511")
 | 
			
		||||
    e   = BigDecimal("2.71828182845904523536028747135266249775724709369996")
 | 
			
		||||
    pow = BigDecimal("22.4591577183610454734271522045437350275893151339967843873233068")
 | 
			
		||||
    pow = BigDecimal("0.2245915771836104547342715220454373502758931513399678438732330680117143493477164265678321738086407229773690574073268002736527e2")
 | 
			
		||||
    assert_equal(pow, pi.power(e))
 | 
			
		||||
 | 
			
		||||
    n = BigDecimal("2222")
 | 
			
		||||
    assert_equal(BigDecimal("0.5171353084572525892492416e12"), (n ** 3.5))
 | 
			
		||||
    assert_equal(BigDecimal("0.517135308457252592e12"), (n ** 3.5r))
 | 
			
		||||
    assert_equal(BigDecimal("0.517135308457252589249241582e12"), (n ** BigDecimal("3.5",15)))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_power_with_prec
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue