AUDIT: r17421 - gnucash/trunk/lib/libqof/qof - Add a new function to the gnc_numeric library that converts denominators to exact powers of ten.

Charles Day cedayiv at cvs.gnucash.org
Sun Jul 27 11:33:24 EDT 2008


Author: cedayiv
Date: 2008-07-27 11:33:23 -0400 (Sun, 27 Jul 2008)
New Revision: 17421
Trac: http://svn.gnucash.org/trac/changeset/17421

Modified:
   gnucash/trunk/lib/libqof/qof/gnc-numeric.c
   gnucash/trunk/lib/libqof/qof/gnc-numeric.h
Log:
Add a new function to the gnc_numeric library that converts denominators to exact powers of ten.
BP


Modified: gnucash/trunk/lib/libqof/qof/gnc-numeric.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-numeric.c	2008-07-27 15:11:19 UTC (rev 17420)
+++ gnucash/trunk/lib/libqof/qof/gnc-numeric.c	2008-07-27 15:33:23 UTC (rev 17421)
@@ -1019,7 +1019,83 @@
   return out;
 }
 
+
 /* *******************************************************************
+ * gnc_numeric_to_decimal
+ *
+ * Attempt to convert the denominator to an exact power of ten without
+ * rounding. TRUE is returned if 'a' has been converted or was already
+ * decimal. Otherwise, FALSE is returned and 'a' remains unchanged.
+ * The 'max_decimal_places' parameter may be NULL.
+ ********************************************************************/
+
+gboolean
+gnc_numeric_to_decimal(gnc_numeric *a, guint8 *max_decimal_places)
+{
+  guint8 decimal_places = 0;
+  gnc_numeric converted_val;
+  gint64 fraction;
+
+  g_return_val_if_fail(a, FALSE);
+
+  if (gnc_numeric_check(*a) != GNC_ERROR_OK) 
+    return FALSE;
+
+  converted_val = *a;
+  fraction = converted_val.denom;
+  if (fraction <= 0)
+    return FALSE;
+
+  while (fraction != 1)
+  {
+    switch (fraction % 10)
+    {
+      case 0:
+        fraction = fraction / 10;
+        break;
+
+      case 5:
+        converted_val = gnc_numeric_mul(converted_val,
+                                        gnc_numeric_create(2, 2),
+                                        GNC_DENOM_AUTO,
+                                        GNC_HOW_DENOM_EXACT |
+                                        GNC_HOW_RND_NEVER);
+        if (gnc_numeric_check(converted_val) != GNC_ERROR_OK)
+          return FALSE;
+        fraction = fraction / 5;
+        break;
+
+      case 2:
+      case 4:
+      case 6:
+      case 8:
+        converted_val = gnc_numeric_mul(converted_val,
+                                        gnc_numeric_create(5, 5),
+                                        GNC_DENOM_AUTO,
+                                        GNC_HOW_DENOM_EXACT |
+                                        GNC_HOW_RND_NEVER);
+        if (gnc_numeric_check(converted_val) != GNC_ERROR_OK)
+          return FALSE;
+        fraction = fraction / 2;
+        break;
+
+      default:
+        return FALSE;
+    }
+
+    decimal_places += 1;
+  }
+
+  if (max_decimal_places)
+    *max_decimal_places = decimal_places;
+
+  *a = converted_val;
+
+  return TRUE;
+}
+
+
+/* *******************************************************************
  *  double_to_gnc_numeric
  ********************************************************************/
 

Modified: gnucash/trunk/lib/libqof/qof/gnc-numeric.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-numeric.h	2008-07-27 15:11:19 UTC (rev 17420)
+++ gnucash/trunk/lib/libqof/qof/gnc-numeric.h	2008-07-27 15:33:23 UTC (rev 17421)
@@ -445,6 +445,21 @@
 /** Return input after reducing it by Greated Common Factor (GCF) 
  *  elimination */
 gnc_numeric gnc_numeric_reduce(gnc_numeric in);
+
+/** Attempt to convert the denominator to an exact power of ten without
+ *  rounding.
+ *
+ *  @param a the ::gnc_numeric value to convert
+ *
+ *  @param max_decimal_places the number of decimal places of the
+ *  converted value. This parameter may be @c NULL.
+ *
+ *  @return @c TRUE if @a a has been converted or was already decimal.
+ *  Otherwise, @c FALSE is returned and @a a and @a max_decimal_places
+ *  remain unchanged.
+ ********************************************************************/
+gboolean gnc_numeric_to_decimal(gnc_numeric * a,
+                                guint8 * max_decimal_places);
 /** @} */
 
 /** @name GValue 



More information about the gnucash-changes mailing list