[前][次][番号順一覧][スレッド一覧]

ruby-changes:64177

From: Kenta <ko1@a...>
Date: Tue, 15 Dec 2020 15:17:35 +0900 (JST)
Subject: [ruby-changes:64177] a86c147579 (master): Import bigdecimal 2.0.2 (#3905)

https://git.ruby-lang.org/ruby.git/commit/?id=a86c147579

From a86c147579745859ea064ec22b2901a7ac7e4abf Mon Sep 17 00:00:00 2001
From: Kenta Murata <mrkn@u...>
Date: Tue, 15 Dec 2020 15:17:15 +0900
Subject: 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@e...>
Co-authored-by: Jeremy Evans <code@j...>

diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index adce9de..bc7fcc6 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -25,7 +25,6 @@ https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L25
 #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) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1791
  * 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) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1807
     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) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1815
     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) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1823
 	}
 	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) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1845
     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) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L2365
 	    }
 	    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) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L2383
 	    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) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L2396
 		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;
 	}
diff --git a/ext/bigdecimal/bigdecimal.gemspec b/ext/bigdecimal/bigdecimal.gemspec
index 5cf0726..980deb0 100644
--- a/ext/bigdecimal/bigdecimal.gemspec
+++ b/ext/bigdecimal/bigdecimal.gemspec
@@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.gemspec#L1
 # coding: utf-8
 
-bigdecimal_version = '2.0.1'
+bigdecimal_version = '2.0.2'
 
 Gem::Specification.new do |s|
   s.name          = "bigdecimal"
diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb
index 11174ad..c8e70ac 100644
--- a/test/bigdecimal/test_bigdecimal.rb
+++ b/test/bigdecimal/test_bigdecimal.rb
@@ -1104,6 +1104,11 @@ class TestBigDecimal < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/bigdecimal/test_bigdecimal.rb#L1104
       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 https://github.com/ruby/ruby/blob/trunk/test/bigdecimal/test_bigdecimal.rb#L1461
   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
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]