r17511 - gnucash/branches/2.2/lib/libqof/qof - [r17421, r17456] Add a new function to the gnc_numeric library that converts denominators to exact powers of ten.

Andreas Köhler andi5 at cvs.gnucash.org
Sun Sep 14 17:29:38 EDT 2008


Author: andi5
Date: 2008-09-14 17:29:38 -0400 (Sun, 14 Sep 2008)
New Revision: 17511
Trac: http://svn.gnucash.org/trac/changeset/17511

Modified:
   gnucash/branches/2.2/lib/libqof/qof/gnc-numeric.c
   gnucash/branches/2.2/lib/libqof/qof/gnc-numeric.h
Log:
[r17421,r17456] Add a new function to the gnc_numeric library that converts denominators to exact powers of ten.

Committed by cedayiv.

Modified: gnucash/branches/2.2/lib/libqof/qof/gnc-numeric.c
===================================================================
--- gnucash/branches/2.2/lib/libqof/qof/gnc-numeric.c	2008-09-14 21:29:30 UTC (rev 17510)
+++ gnucash/branches/2.2/lib/libqof/qof/gnc-numeric.c	2008-09-14 21:29:38 UTC (rev 17511)
@@ -1019,7 +1019,87 @@
   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;
+  if (converted_val.denom <= 0)
+    return FALSE;
+
+  /* Zero is easily converted. */
+  if (converted_val.num == 0)
+    converted_val.denom = 1;
+
+  fraction = converted_val.denom;
+  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/branches/2.2/lib/libqof/qof/gnc-numeric.h
===================================================================
--- gnucash/branches/2.2/lib/libqof/qof/gnc-numeric.h	2008-09-14 21:29:30 UTC (rev 17510)
+++ gnucash/branches/2.2/lib/libqof/qof/gnc-numeric.h	2008-09-14 21:29:38 UTC (rev 17511)
@@ -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