2010-03-03 Miguel de Icaza <miguel@novell.com>
authorMiguel de Icaza <miguel@gnome.org>
Wed, 3 Mar 2010 17:29:54 +0000 (17:29 -0000)
committerMiguel de Icaza <miguel@gnome.org>
Wed, 3 Mar 2010 17:29:54 +0000 (17:29 -0000)
* decimal.c (mono_double2decimal): Add support for reducing the
scale of a decimal.  It turns the 0.6000000000000 into 0.6 as
expected.

svn path=/trunk/mono/; revision=152952

mono/metadata/ChangeLog
mono/metadata/decimal.c

index 33a78f4d159a225ce52efaf40ea956e0b2cced83..c5a866bee04c07007301a708f912b7f51f8f86ae 100644 (file)
@@ -1,3 +1,9 @@
+2010-03-03  Miguel de Icaza  <miguel@novell.com>
+
+       * decimal.c (mono_double2decimal): Add support for reducing the
+       scale of a decimal.  It turns the 0.6000000000000 into 0.6 as
+       expected.
+
 2010-03-03 Rodrigo Kumpera  <rkumpera@novell.com>
 
        * icall-def.h:
index 6524443eab3d57168325a710d2ac93e05d74671a..b2170be7605165cfa8d164ad87115ac594c85145 100644 (file)
@@ -767,6 +767,34 @@ DECINLINE static int rescale128(guint64* pclo, guint64* pchi, int* pScale, int t
     return normalize128(pclo, pchi, pScale, roundFlag, roundBit);
 }
 
+guint32 rest;
+static void trimExcessScale(guint64* pclo, guint64* pchi, int* pScale)
+{
+       guint64 ilo = *pclo, lastlo;
+       guint64 ihi = *pchi, lasthi;
+       int scale = *pScale;
+       int i = 0, roundBit;
+       
+       while (scale > 0) {
+               scale--;
+               i++;
+               lastlo = ilo;
+               lasthi = ihi;
+               
+               roundBit = div128by32(&ilo, &ihi, 10, &rest);
+               if (rest != 0){
+                       i--;
+                       if (i == 0)
+                               return;
+
+                       *pclo = lastlo;
+                       *pchi = lasthi;
+                       *pScale = scale+1;
+                       return;
+               }
+       }
+}
+
 /* performs a += b */
 gint32 mono_decimalIncr(/*[In, Out]*/decimal_repr* pA, /*[In]*/decimal_repr* pB)
 {
@@ -948,6 +976,14 @@ gint32 mono_double2decimal(/*[Out]*/decimal_repr* pA, double val, gint32 digits)
         }
     }
 
+    //
+    // Turn the double 0.6 which at this point is:
+    // 0.6000000000000000
+    // into:
+    // 0.6
+    //
+    trimExcessScale (&alo, &ahi, &scale);
+    
     return pack128toDecimal(pA, alo, ahi, scale, sign);
 }