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

ruby-changes:31685

From: mrkn <ko1@a...>
Date: Thu, 21 Nov 2013 21:37:53 +0900 (JST)
Subject: [ruby-changes:31685] mrkn:r43764 (trunk): * ext/bigdecimal/bigdecimal.c (BigDecimal_sqrt): Fix the precision of

mrkn	2013-11-21 21:37:46 +0900 (Thu, 21 Nov 2013)

  New Revision: 43764

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=43764

  Log:
    * ext/bigdecimal/bigdecimal.c (BigDecimal_sqrt): Fix the precision of
      the result BigDecimal of sqrt.
      [Bug #5266] [ruby-dev:44450]
    
    * test/bigdecimal/test_bigdecimal.rb: add tests for the above changes.

  Modified files:
    trunk/ChangeLog
    trunk/ext/bigdecimal/bigdecimal.c
    trunk/test/bigdecimal/test_bigdecimal.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 43763)
+++ ChangeLog	(revision 43764)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Nov 21 21:36:00 2013  Kenta Murata  <mrkn@m...>
+
+	* ext/bigdecimal/bigdecimal.c (BigDecimal_sqrt): Fix the precision of
+	  the result BigDecimal of sqrt.
+	  [Bug #5266] [ruby-dev:44450]
+
+	* test/bigdecimal/test_bigdecimal.rb: add tests for the above changes.
+
 Thu Nov 21 18:49:02 2013  Nobuyoshi Nakada  <nobu@r...>
 
 	* gc.c (vm_xrealloc, vm_xfree): use malloc_usable_size() to obtain old
Index: ext/bigdecimal/bigdecimal.c
===================================================================
--- ext/bigdecimal/bigdecimal.c	(revision 43763)
+++ ext/bigdecimal/bigdecimal.c	(revision 43764)
@@ -1591,10 +1591,10 @@ BigDecimal_sqrt(VALUE self, VALUE nFig) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1591
     size_t mx, n;
 
     GUARD_OBJ(a, GetVpValue(self, 1));
-    mx = a->Prec *(VpBaseFig() + 1);
+    mx = a->Prec * (VpBaseFig() + 1);
 
-    n = GetPositiveInt(nFig) + VpDblFig() + 1;
-    if(mx <= n) mx = n;
+    n = GetPositiveInt(nFig) + VpDblFig() + BASE_FIG;
+    if (mx <= n) mx = n;
     GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
     VpSqrt(c, a);
     return ToValue(c);
@@ -5654,6 +5654,7 @@ VpSqrt(Real *y, Real *x) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L5654
 
     n = (SIGNED_VALUE)y->MaxPrec;
     if (x->MaxPrec > (size_t)n) n = (ssize_t)x->MaxPrec;
+
     /* allocate temporally variables  */
     f = VpAlloc(y->MaxPrec * (BASE_FIG + 2), "#1");
     r = VpAlloc((n + n) * (BASE_FIG + 2), "#1");
@@ -5691,8 +5692,7 @@ VpSqrt(Real *y, Real *x) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L5692
 	if (VpIsZero(f))         goto converge;
 	VpAddSub(r, f, y, 1);    /* r = y + f  */
 	VpAsgn(y, r, 1);         /* y = r      */
-	if (f->exponent <= prec) goto converge;
-    } while(++nr < n);
+    } while (++nr < n);
 
 #ifdef BIGDECIMAL_DEBUG
     if (gfDebug) {
Index: test/bigdecimal/test_bigdecimal.rb
===================================================================
--- test/bigdecimal/test_bigdecimal.rb	(revision 43763)
+++ test/bigdecimal/test_bigdecimal.rb	(revision 43764)
@@ -804,6 +804,20 @@ class TestBigDecimal < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/bigdecimal/test_bigdecimal.rb#L804
     assert_equal(1, BigDecimal.new("1").sqrt(1))
   end
 
+  def test_sqrt_5266
+    x = BigDecimal('2' + '0'*100)
+    assert_equal('0.14142135623730950488016887242096980785696718753769480731',
+                 x.sqrt(56).to_s(56).split(' ')[0])
+    assert_equal('0.1414213562373095048801688724209698078569671875376948073',
+                 x.sqrt(55).to_s(55).split(' ')[0])
+
+    x = BigDecimal('2' + '0'*200)
+    assert_equal('0.14142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462',
+                 x.sqrt(110).to_s(110).split(' ')[0])
+    assert_equal('0.1414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641572735013846',
+                 x.sqrt(109).to_s(109).split(' ')[0])
+  end
+
   def test_fix
     x = BigDecimal.new("1.1")
     assert_equal(1, x.fix)

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

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