[Gnucash-changes] finish folding in the now-obsolete texinfo
documentation
Linas Vepstas
linas at cvs.gnucash.org
Sat Jun 26 23:57:26 EDT 2004
Log Message:
-----------
finish folding in the now-obsolete texinfo documentation
Modified Files:
--------------
gnucash/src/engine:
gnc-numeric.c
gnc-numeric.h
Revision Data
-------------
Index: gnc-numeric.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-numeric.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -Lsrc/engine/gnc-numeric.c -Lsrc/engine/gnc-numeric.c -u -r1.43 -r1.44
--- src/engine/gnc-numeric.c
+++ src/engine/gnc-numeric.c
@@ -34,11 +34,6 @@
#include "gnc-numeric.h"
-/* TODO
- * - use longer intermediate values to make operations
- * 64-bit-overflow-proof
- */
-
/* static short module = MOD_ENGINE; */
/* =============================================================== */
@@ -365,8 +360,8 @@
"No error",
"Argument is not a valid number",
"Intermediate result overflow",
- "Argument denominators differ in GNC_DENOM_FIXED operation",
- "Remainder part in GNC_RND_NEVER operation"
+ "Argument denominators differ in GNC_HOW_DENOM_FIXED operation",
+ "Remainder part in GNC_HOW_RND_NEVER operation"
};
#endif
@@ -606,7 +601,7 @@
}
if((denom == GNC_DENOM_AUTO) &&
- (how & GNC_NUMERIC_DENOM_MASK) == GNC_DENOM_FIXED)
+ (how & GNC_NUMERIC_DENOM_MASK) == GNC_HOW_DENOM_FIXED)
{
if(a.denom == b.denom) {
denom = a.denom;
@@ -668,7 +663,7 @@
}
if((denom == GNC_DENOM_AUTO) &&
- ((how & GNC_NUMERIC_DENOM_MASK) == GNC_DENOM_LCD))
+ ((how & GNC_NUMERIC_DENOM_MASK) == GNC_HOW_DENOM_LCD))
{
denom = gnc_numeric_lcd(a, b);
how = how & GNC_NUMERIC_RND_MASK;
@@ -711,7 +706,7 @@
}
if((denom == GNC_DENOM_AUTO) &&
- (how & GNC_NUMERIC_DENOM_MASK) == GNC_DENOM_FIXED) {
+ (how & GNC_NUMERIC_DENOM_MASK) == GNC_HOW_DENOM_FIXED) {
if(a.denom == b.denom) {
denom = a.denom;
}
@@ -758,7 +753,7 @@
#endif
if((denom == GNC_DENOM_AUTO) &&
- ((how & GNC_NUMERIC_DENOM_MASK) == GNC_DENOM_LCD))
+ ((how & GNC_NUMERIC_DENOM_MASK) == GNC_HOW_DENOM_LCD))
{
denom = gnc_numeric_lcd(a, b);
how = how & GNC_NUMERIC_RND_MASK;
@@ -785,7 +780,7 @@
}
if((denom == GNC_DENOM_AUTO) &&
- (how & GNC_NUMERIC_DENOM_MASK) == GNC_DENOM_FIXED)
+ (how & GNC_NUMERIC_DENOM_MASK) == GNC_HOW_DENOM_FIXED)
{
if(a.denom == b.denom)
{
@@ -880,7 +875,7 @@
}
if((denom == GNC_DENOM_AUTO) &&
- ((how & GNC_NUMERIC_DENOM_MASK) == GNC_DENOM_LCD))
+ ((how & GNC_NUMERIC_DENOM_MASK) == GNC_HOW_DENOM_LCD))
{
denom = gnc_numeric_lcd(a, b);
how = how & GNC_NUMERIC_RND_MASK;
@@ -942,17 +937,17 @@
switch(how & GNC_NUMERIC_DENOM_MASK)
{
default:
- case GNC_DENOM_LCD: /* LCD is meaningless with AUTO in here */
- case GNC_DENOM_EXACT:
+ case GNC_HOW_DENOM_LCD: /* LCD is meaningless with AUTO in here */
+ case GNC_HOW_DENOM_EXACT:
return in;
break;
- case GNC_DENOM_REDUCE:
+ case GNC_HOW_DENOM_REDUCE:
/* reduce the input to a relatively-prime fraction */
return gnc_numeric_reduce(in);
break;
- case GNC_DENOM_FIXED:
+ case GNC_HOW_DENOM_FIXED:
if(in.denom != denom) {
return gnc_numeric_error(GNC_ERROR_DENOM_DIFF);
}
@@ -961,7 +956,7 @@
}
break;
- case GNC_DENOM_SIGFIG:
+ case GNC_HOW_DENOM_SIGFIG:
ratio = fabs(gnc_numeric_to_double(in));
if(ratio < 10e-20) {
logratio = 0;
@@ -971,7 +966,7 @@
logratio = ((logratio > 0.0) ?
(floor(logratio)+1.0) : (ceil(logratio)));
}
- sigfigs = GNC_NUMERIC_GET_SIGFIGS(how);
+ sigfigs = GNC_HOW_GET_SIGFIGS(how);
if(sigfigs-logratio >= 0) {
denom = (gint64)(pow(10, sigfigs-logratio));
@@ -980,7 +975,7 @@
denom = -((gint64)(pow(10, logratio-sigfigs)));
}
- how = how & ~GNC_DENOM_SIGFIG & ~GNC_NUMERIC_SIGFIGS_MASK;
+ how = how & ~GNC_HOW_DENOM_SIGFIG & ~GNC_NUMERIC_SIGFIGS_MASK;
break;
}
@@ -1030,26 +1025,26 @@
if(remainder > 0)
{
switch(how) {
- case GNC_RND_FLOOR:
+ case GNC_HOW_RND_FLOOR:
if(sign < 0) {
out.num = out.num + 1;
}
break;
- case GNC_RND_CEIL:
+ case GNC_HOW_RND_CEIL:
if(sign > 0) {
out.num = out.num + 1;
}
break;
- case GNC_RND_TRUNC:
+ case GNC_HOW_RND_TRUNC:
break;
- case GNC_RND_PROMOTE:
+ case GNC_HOW_RND_PROMOTE:
out.num = out.num + 1;
break;
- case GNC_RND_ROUND_HALF_DOWN:
+ case GNC_HOW_RND_ROUND_HALF_DOWN:
if(denom_neg) {
if((2 * remainder) > in.denom*denom) {
out.num = out.num + 1;
@@ -1060,7 +1055,7 @@
}
break;
- case GNC_RND_ROUND_HALF_UP:
+ case GNC_HOW_RND_ROUND_HALF_UP:
if(denom_neg) {
if((2 * remainder) >= in.denom*denom) {
out.num = out.num + 1;
@@ -1071,7 +1066,7 @@
}
break;
- case GNC_RND_ROUND:
+ case GNC_HOW_RND_ROUND:
if(denom_neg) {
if((2 * remainder) > in.denom*denom) {
out.num = out.num + 1;
@@ -1094,7 +1089,7 @@
}
break;
- case GNC_RND_NEVER:
+ case GNC_HOW_RND_NEVER:
return gnc_numeric_error(GNC_ERROR_REMAINDER);
break;
}
@@ -1108,7 +1103,7 @@
/********************************************************************
** reduce a fraction by GCF elimination. This is NOT done as a
- * part of the arithmetic API unless GNC_DENOM_REDUCE is specified
+ * part of the arithmetic API unless GNC_HOW_DENOM_REDUCE is specified
* as the output denominator.
********************************************************************/
@@ -1154,7 +1149,8 @@
double logval;
double sigfigs;
- if((denom == GNC_DENOM_AUTO) && (how & GNC_DENOM_SIGFIG)) {
+ if((denom == GNC_DENOM_AUTO) && (how & GNC_HOW_DENOM_SIGFIG))
+ {
if(fabs(in) < 10e-20) {
logval = 0;
}
@@ -1163,7 +1159,7 @@
logval = ((logval > 0.0) ?
(floor(logval)+1.0) : (ceil(logval)));
}
- sigfigs = GNC_NUMERIC_GET_SIGFIGS(how);
+ sigfigs = GNC_HOW_GET_SIGFIGS(how);
if(sigfigs-logval >= 0) {
denom = (gint64)(pow(10, sigfigs-logval));
}
@@ -1171,7 +1167,7 @@
denom = -((gint64)(pow(10, logval-sigfigs)));
}
- how = how & ~GNC_DENOM_SIGFIG & ~GNC_NUMERIC_SIGFIGS_MASK;
+ how = how & ~GNC_HOW_DENOM_SIGFIG & ~GNC_NUMERIC_SIGFIGS_MASK;
}
int_part = (gint64)(floor(fabs(in)));
@@ -1181,24 +1177,24 @@
frac_part = frac_part * (double)denom;
switch(how & GNC_NUMERIC_RND_MASK) {
- case GNC_RND_FLOOR:
+ case GNC_HOW_RND_FLOOR:
frac_int = (gint64)floor(frac_part);
break;
- case GNC_RND_CEIL:
+ case GNC_HOW_RND_CEIL:
frac_int = (gint64)ceil(frac_part);
break;
- case GNC_RND_TRUNC:
+ case GNC_HOW_RND_TRUNC:
frac_int = (gint64)frac_part;
break;
- case GNC_RND_ROUND:
- case GNC_RND_ROUND_HALF_UP:
+ case GNC_HOW_RND_ROUND:
+ case GNC_HOW_RND_ROUND_HALF_UP:
frac_int = (gint64)rint(frac_part);
break;
- case GNC_RND_NEVER:
+ case GNC_HOW_RND_NEVER:
frac_int = (gint64)floor(frac_part);
if(frac_part != (double) frac_int) {
/* signal an error */
@@ -1226,21 +1222,6 @@
}
}
-
-/********************************************************************
- * gnc_numeric_create
- ********************************************************************/
-
-gnc_numeric
-gnc_numeric_create(gint64 num, gint64 denom)
-{
- gnc_numeric out;
- out.num = num;
- out.denom = denom;
- return out;
-}
-
-
/********************************************************************
* gnc_numeric_error
********************************************************************/
@@ -1253,39 +1234,6 @@
/********************************************************************
- * gnc_numeric_zero
- ********************************************************************/
-
-gnc_numeric
-gnc_numeric_zero(void)
-{
- return gnc_numeric_create(0LL, 1LL);
-}
-
-
-/********************************************************************
- * gnc_numeric_num
- ********************************************************************/
-
-gint64
-gnc_numeric_num(gnc_numeric a)
-{
- return a.num;
-}
-
-
-/********************************************************************
- * gnc_numeric_denom
- ********************************************************************/
-
-gint64
-gnc_numeric_denom(gnc_numeric a)
-{
- return a.denom;
-}
-
-
-/********************************************************************
* gnc_numeric_add_with_error
********************************************************************/
@@ -1297,9 +1245,9 @@
gnc_numeric sum = gnc_numeric_add(a, b, denom, how);
gnc_numeric exact = gnc_numeric_add(a, b, GNC_DENOM_AUTO,
- GNC_DENOM_REDUCE);
+ GNC_HOW_DENOM_REDUCE);
gnc_numeric err = gnc_numeric_sub(sum, exact, GNC_DENOM_AUTO,
- GNC_DENOM_REDUCE);
+ GNC_HOW_DENOM_REDUCE);
if(error) {
*error = err;
@@ -1318,9 +1266,9 @@
{
gnc_numeric diff = gnc_numeric_sub(a, b, denom, how);
gnc_numeric exact = gnc_numeric_sub(a, b, GNC_DENOM_AUTO,
- GNC_DENOM_REDUCE);
+ GNC_HOW_DENOM_REDUCE);
gnc_numeric err = gnc_numeric_sub(diff, exact, GNC_DENOM_AUTO,
- GNC_DENOM_REDUCE);
+ GNC_HOW_DENOM_REDUCE);
if(error) {
*error = err;
}
@@ -1339,9 +1287,9 @@
{
gnc_numeric prod = gnc_numeric_mul(a, b, denom, how);
gnc_numeric exact = gnc_numeric_mul(a, b, GNC_DENOM_AUTO,
- GNC_DENOM_REDUCE);
+ GNC_HOW_DENOM_REDUCE);
gnc_numeric err = gnc_numeric_sub(prod, exact, GNC_DENOM_AUTO,
- GNC_DENOM_REDUCE);
+ GNC_HOW_DENOM_REDUCE);
if(error) {
*error = err;
}
@@ -1360,9 +1308,9 @@
{
gnc_numeric quot = gnc_numeric_div(a, b, denom, how);
gnc_numeric exact = gnc_numeric_div(a, b, GNC_DENOM_AUTO,
- GNC_DENOM_REDUCE);
+ GNC_HOW_DENOM_REDUCE);
gnc_numeric err = gnc_numeric_sub(quot, exact,
- GNC_DENOM_AUTO, GNC_DENOM_REDUCE);
+ GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
if(error) {
*error = err;
}
@@ -1444,25 +1392,25 @@
gnc_numeric err;
- c = gnc_numeric_add_with_error(a, b, 100, GNC_RND_ROUND, &err);
+ c = gnc_numeric_add_with_error(a, b, 100, GNC_HOW_RND_ROUND, &err);
printf("add 100ths/error : %s + %s = %s + (error) %s\n\n",
gnc_numeric_print(a), gnc_numeric_print(b),
gnc_numeric_print(c),
gnc_numeric_print(err));
- c = gnc_numeric_sub_with_error(a, b, 100, GNC_RND_FLOOR, &err);
+ c = gnc_numeric_sub_with_error(a, b, 100, GNC_HOW_RND_FLOOR, &err);
printf("sub 100ths/error : %s - %s = %s + (error) %s\n\n",
gnc_numeric_print(a), gnc_numeric_print(b),
gnc_numeric_print(c),
gnc_numeric_print(err));
- c = gnc_numeric_mul_with_error(a, b, 100, GNC_RND_ROUND, &err);
+ c = gnc_numeric_mul_with_error(a, b, 100, GNC_HOW_RND_ROUND, &err);
printf("mul 100ths/error : %s * %s = %s + (error) %s\n\n",
gnc_numeric_print(a), gnc_numeric_print(b),
gnc_numeric_print(c),
gnc_numeric_print(err));
- c = gnc_numeric_div_with_error(a, b, 100, GNC_RND_ROUND, &err);
+ c = gnc_numeric_div_with_error(a, b, 100, GNC_HOW_RND_ROUND, &err);
printf("div 100ths/error : %s / %s = %s + (error) %s\n\n",
gnc_numeric_print(a), gnc_numeric_print(b),
gnc_numeric_print(c),
@@ -1470,11 +1418,11 @@
printf("multiply (EXACT): %s * %s = %s\n",
gnc_numeric_print(a), gnc_numeric_print(b),
- gnc_numeric_print(gnc_numeric_mul(a, b, GNC_DENOM_AUTO, GNC_DENOM_EXACT)));
+ gnc_numeric_print(gnc_numeric_mul(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT)));
printf("multiply (REDUCE): %s * %s = %s\n",
gnc_numeric_print(a), gnc_numeric_print(b),
- gnc_numeric_print(gnc_numeric_mul(a, b, GNC_DENOM_AUTO, GNC_DENOM_REDUCE)));
+ gnc_numeric_print(gnc_numeric_mul(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE)));
return 0;
Index: gnc-numeric.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-numeric.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -Lsrc/engine/gnc-numeric.h -Lsrc/engine/gnc-numeric.h -u -r1.19 -r1.20
--- src/engine/gnc-numeric.h
+++ src/engine/gnc-numeric.h
@@ -27,7 +27,7 @@
where the denominator typically represents the smallest fraction
of the currency (e.g. pennies, centimes). The numeric class
can handle any fraction (e.g. twelfth's) and is not limited
- to fractions that are powers of ten.
+ to fractions that are powers of ten.
A 'Numeric' value represents a number in rational form, with a
64-bit integer as numerator and denominator. Rationals are
@@ -42,204 +42,10 @@
@author Copyright (C) 2004 Linas Vepstas <linas at linas.org>
*/
-#if JUNK
-
-/*******************
- at menu
-* Standard Numeric Arguments::
-* Creating Numeric Objects::
-* Basic Arithmetic Operations::
-* Numeric Comparisons and Predicates::
-* Numeric Denominator Conversion::
-* Numeric Floating Point Conversion::
-* Numeric String Conversion::
-* Numeric Error Handling ::
-* Numeric Example::
- at end menu
-
- at node Standard Numeric Arguments, Creating Numeric Objects, Numeric Library, Numeric Library
- at subsection Standard Numeric Arguments
- at cindex Standard Numeric Arguments
-
-It is useful to specify a denominator in cases where it is known that
-the output value is of constrained precision. For example, monetary
-transactions must be executed in an integer number of the "smallest
-currency unit" of the transaction. In US Dollars, the smallest currency
-unit is the cent, and all monetary transactions must be done in units of
-cents. Therefore, any fractional cents in a computed price must be
-rounded away.
-
-Most of the @code{gnc_numeric} arithmetic functions take two arguments
-in addition to their numeric args: @var{denom}, which is the denominator
-to use in the output @code{gnc_numeric object}, and @var{how}, which
-describes how the arithmetic result is to be converted to that
-denominator. This combination of output denominator and rounding policy
-allows the results of financial and other exact computations to be
-properly rounded to the appropriate units.
-
-Valid values for @var{denom} are:
-
-Valid values for @var{how} are bitwise combinations of zero or one
-"rounding instructions" with zero or one "denominator types".
-
-The denominator type specifies how to compute a denominator if
- at code{GNC_DENOM_AUTO} is specified as the @var{denom}. Valid denominator
-types are:
-
-
-
-To use traditional rational-number operational semantics (all results
-are exact and are reduced to relatively-prime fractions) pass the
-argument @code{GNC_DENOM_AUTO} as @var{denom} and @code{GNC_DENOM_REDUCE
-| GNC_RND_NEVER} as @var{how}.
-
-To enforce strict financial semantics (such that all operands must have
-the same denominator as each other and as the result), use
- at var{GNC_DENOM_AUTO} as @var{denom} and @code{GNC_DENOM_FIXED |
-GNC_RND_NEVER} as @var{how}.
-
-
- at node Creating Numeric Objects, Basic Arithmetic Operations, Standard Numeric Arguments, Numeric Library
- at subsection Creating Numeric Objects
- at cindex Creating Numeric Objects
-
- at deftypefun gnc_numeric gnc_numeric_create (int @var{num}, int @var{denom})
-Create a @code{gnc_numeric} object with a value of "@var{num} / @var{denom}".
- at end deftypefun
-
- at deftypefun gnc_numeric gnc_numeric_zero ()
-Create a @code{gnc_numeric} object with a value of 0.
- at end deftypefun
-
-
- at node Basic Arithmetic Operations, Numeric Comparisons and Predicates, Creating Numeric Objects, Numeric Library
- at subsection Basic Arithmetic Operations
- at cindex Basic Arithmetic Operations
-
-See @ref{Standard Numeric Arguments} for a description of the @var{denom}
-and @var{how} arguments to each arithmetic function.
-
- at deftypefun gnc_numeric gnc_numeric_add (gnc_numeric @var{a}, gnc_numeric @var{b}, gint64 @var{denom}, gint @var{how})
-Return the sum of @var{a} and @var{b}.
- at end deftypefun
-
- at deftypefun gnc_numeric gnc_numeric_sub (gnc_numeric @var{a}, gnc_numeric @var{b}, gint64 @var{denom}, gint @var{how})
-Return "@var{a} - @var{b}".
- at end deftypefun
-
- at deftypefun gnc_numeric gnc_numeric_div (gnc_numeric @var{a}, gnc_numeric @var{b}, gint64 @var{denom}, gint @var{how})
-Return "@var{a} / @var{b}".
- at end deftypefun
-
- at deftypefun gnc_numeric gnc_numeric_add_with_error (gnc_numeric @var{a}, gnc_numeric @var{b}, gint64 @var{denom}, gint @var{how}, {gnc_numeric *} @var{error})
-The same as @code{gnc_numeric_add}, but uses @var{error} for accumulating
-conversion roundoff error.
- at end deftypefun
-
- at deftypefun gnc_numeric gnc_numeric_sub_with_error (gnc_numeric @var{a}, gnc_numeric @var{b}, gint64 @var{denom}, gint @var{how}, {gnc_numeric *} @var{error})
-The same as @code{gnc_numeric_sub}, but uses @var{error} for accumulating
-conversion roundoff error.
- at end deftypefun
-
- at deftypefun gnc_numeric gnc_numeric_div_with_error (gnc_numeric @var{a}, gnc_numeric @var{b}, gint64 @var{denom}, gint @var{how}, {gnc_numeric *} @var{error})
-The same as @code{gnc_numeric_div}, but uses @var{error} for accumulating
-conversion roundoff error.
- at end deftypefun
-
-
- at node Numeric Comparisons and Predicates, Numeric Denominator Conversion, Basic Arithmetic Operations, Numeric Library
- at subsection Numeric Comparisons and Predicates
- at cindex Numeric Comparisons and Predicates
-
- at deftypefun int gnc_numeric_compare (gnc_numeric @var{a}, gnc_numeric @var{b})
-Returns +1 if @code{@var{a} > @var{b}}, -1 if @code{@var{b} > @var{a}}, 0 if @code{@var{a} == @var{b}}.
- at end deftypefun
-
- at deftypefun int gnc_numeric_eq (gnc_numeric @var{a}, gnc_numeric @var{b})
-Returns 1 if @code{numerator(@var{a}) == numerator(@var{b})} and
- at code{denominator(@var{a}) == denominator(@var{b})}, otherwise returns 0.
- at end deftypefun
-
- at deftypefun int gnc_numeric_equal (gnc_numeric @var{a}, gnc_numeric @var{b})
-Returns 1 if the fraction represented by @var{a} is equal to the fraction
-represented by @var{b}, otherwise returns 0.
- at end deftypefun
-
- at deftypefun int gnc_numeric_same (gnc_numeric @var{a}, gnc_numeric @var{b}, gint64 @var{denom}, gint @var{how})
-Convert both @var{a} and @var{b} to @var{denom} (@pxref{Standard Numeric
-Arguments} and compare numerators of the result.
-
- at example
- For example, if @code{@var{a} == 7/16} and @code{@var{b} == 3/4},
- @code{gnc_numeric_same(@var{a}, @var{b}, 2, GNC_RND_TRUNC) == 1}
- because both 7/16 and 3/4 round to 1/2 under truncation. However,
- @code{gnc_numeric_same(@var{a}, @var{b}, 2, GNC_RND_ROUND) == 0}
- because 7/16 rounds to 1/2 under unbiased rounding but 3/4 rounds
- to 2/2.
- at end example
- at end deftypefun
-
-
- at node Numeric Denominator Conversion, Numeric Floating Point Conversion, Numeric Comparisons and Predicates, Numeric Library
- at subsection Numeric Denominator Conversion
- at cindex Numeric Denominator Conversion
-
- at deftypefun gnc_numeric gnc_numeric_convert (gnc_numeric @var{in}, gint64 @var{denom}, gint @var{how})
-Convert @var{in} to the specified denominator under standard arguments
- at var{denom} and @var{how}. @xref{Standard Numeric Arguments}.
- at end deftypefun
-
- at deftypefun gnc_numeric gnc_numeric_convert_with_error (gnc_numeric @var{in}, gint64 @var{denom}, gint @var{how}, {gnc_numeric *} @var{error})
-Same as @code{gnc_numeric_convert}, but return a remainder value for
-accumulating conversion error.
- at end deftypefun
-
- at node Numeric Floating Point Conversion, Numeric String Conversion, Numeric Denominator Conversion, Numeric Library
- at subsection Numeric Floating Point Conversion
- at cindex Numeric Floating Point Conversion
-
- at deftypefun gnc_numeric double_to_gnc_numeric (double @var{arg}, gint64 @var{denom}, gint @var{how})
-Convert a floating-point number to a @code{gnc_numeric}. Both @var{denom}
-and @var{how} are used as in arithmetic, but @code{GNC_DENOM_AUTO} is
-not recognized.
- at end deftypefun
-
- at deftypefun double gnc_numeric_to_double (gnc_numeric @var{arg})
-Convert @var{arg} to a @code{double} value.
- at end deftypefun
-
-
- at node Numeric String Conversion, Numeric Error Handling , Numeric Floating Point Conversion, Numeric Library
- at subsection Numeric String Conversion
- at cindex Numeric String Conversion
-
- at deftypefun {gchar *} gnc_numeric_to_string (gnc_numeric @var{n})
-Return a string representation of @var{n}. The string must be
-freed with @code{g_free}.
- at end deftypefun
-
- at deftypefun {const gchar *} string_to_gnc_numeric (const {gchar *} @var{str}, {gnc_numeric *} @var{n})
-Read a @code{gnc_numeric} from @var{str}, skipping any leading
-whitespace, and returning a pointer to just past the last byte
-read. Return NULL on error.
- at end deftypefun
-
-
- at node Numeric Error Handling , Numeric Example, Numeric String Conversion, Numeric Library
- at subsection Numeric Error Handling
- at cindex Numeric Error Handling
-
-
- at deftypefun gnc_numeric gnc_numeric_error (int error_code)
-Create a @code{gnc_numeric} object that signals the error condition
-noted by @var{error_code} rather than a number.
- at end deftypefun
-
-
- at node Numeric Example, , Numeric Error Handling , Numeric Library
- at subsection Numeric Example
- at cindex Numeric Example
+/** ----------------------------------------------------------
+EXAMPLE
+-------
The following program finds the best @code{gnc_numeric} approximation to
the @file{math.h} constant @code{M_PI} given a maximum denominator. For
large denominators, the @code{gnc_numeric} approximation is accurate to
@@ -260,7 +66,7 @@
int
main(int argc, char ** argv)
-@{
+{
gnc_numeric approx, best;
double err, best_err=1.0;
double m_pi = M_PI;
@@ -270,43 +76,90 @@
sscanf(argv[1], "%Ld", &max);
for (denom = 1; denom < max; denom++)
- @{
+ {
approx = double_to_gnc_numeric (m_pi, denom, GNC_RND_ROUND);
err = m_pi - gnc_numeric_to_double (approx);
if (fabs (err) < fabs (best_err))
- @{
+ {
best = approx;
best_err = err;
printf ("%Ld / %Ld = %.30f\n", gnc_numeric_num (best),
gnc_numeric_denom (best), gnc_numeric_to_double (best));
- @}
- @}
-@}
- at end example
-
-**********************/
-#endif
+ }
+ }
+}
+----------------------------------------------------------------- */
#ifndef GNC_NUMERIC_H
#define GNC_NUMERIC_H
#include <glib.h>
-struct _gnc_numeric {
+struct _gnc_numeric
+{
gint64 num;
gint64 denom;
};
-/** @brief An exact-number type
+/** @brief An rational-number type
*
- * This is a rational number, defined by nominator and denominator. */
+ * This is a rational number, defined by numerator and denominator. */
typedef struct _gnc_numeric gnc_numeric;
+/** @name Arguments
+ * @brief Standard Arguments to most functions
+
+ Most of the gnc_numeric arithmetic functions take two arguments
+ in addition to their numeric args: @var{denom}, which is the denominator
+ to use in the output @code{gnc_numeric object}, and @var{how}, which
+ describes how the arithmetic result is to be converted to that
+ denominator. This combination of output denominator and rounding policy
+ allows the results of financial and other rational computations to be
+ properly rounded to the appropriate units.
+
+ Valid values for @var{denom} are:
+ GNC_DENOM_AUTO -- compute denominator exactly
+ integer n -- Force the denominator of teh result to be this integer
+ GNC_DENOM_RECIPROCAL -- Use 1/n as the denominator (???huh???)
+
+ Valid values for @var{how} are bitwise combinations of zero or one
+ "rounding instructions" with zero or one "denominator types".
+ Valid rounding instructions are:
+ GNC_HOW_RND_FLOOR
+ GNC_HOW_RND_CEIL
+ GNC_HOW_RND_TRUNC
+ GNC_HOW_RND_PROMOTE
+ GNC_HOW_RND_ROUND_HALF_DOWN
+ GNC_HOW_RND_ROUND_HALF_UP
+ GNC_HOW_RND_ROUND
+ GNC_HOW_RND_NEVER
+
+ The denominator type specifies how to compute a denominator if
+ @code{GNC_DENOM_AUTO} is specified as the @var{denom}. Valid
+ denominator types are:
+ GNC_HOW_DENOM_EXACT
+ GNC_HOW_DENOM_REDUCE
+ GNC_HOW_DENOM_LCD
+ GNC_HOW_DENOM_FIXED
+ GNC_HOW_DENOM_SIGFIGS(N)
+
+ To use traditional rational-number operational semantics (all results
+ are exact and are reduced to relatively-prime fractions) pass the
+ argument @code{GNC_DENOM_AUTO} as @var{denom} and
+ @code{GNC_HOW_DENOM_REDUCE| GNC_HOW_RND_NEVER} as @var{how}.
+
+ To enforce strict financial semantics (such that all operands must have
+ the same denominator as each other and as the result), use
+ @var{GNC_DENOM_AUTO} as @var{denom} and
+ @code{GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER} as @var{how}.
+
+ @{ */
+
/** bitmasks for HOW flags.
* bits 8-15 of 'how' are reserved for the number of significant
- * digits to use in the output with GNC_DENOM_SIGFIG */
-
+ * digits to use in the output with GNC_HOW_DENOM_SIGFIG
+ */
#define GNC_NUMERIC_RND_MASK 0x0000000f
#define GNC_NUMERIC_DENOM_MASK 0x000000f0
#define GNC_NUMERIC_SIGFIGS_MASK 0x0000ff00
@@ -321,38 +174,38 @@
*/
enum {
/** Round toward -infinity */
- GNC_RND_FLOOR = 0x01,
+ GNC_HOW_RND_FLOOR = 0x01,
/** Round toward +infinity */
- GNC_RND_CEIL = 0x02,
+ GNC_HOW_RND_CEIL = 0x02,
/** Truncate fractions (round toward zero) */
- GNC_RND_TRUNC = 0x03,
+ GNC_HOW_RND_TRUNC = 0x03,
/** Promote fractions (round away from zero) */
- GNC_RND_PROMOTE = 0x04,
+ GNC_HOW_RND_PROMOTE = 0x04,
/** Round to the nearest integer, rounding toward zero
* when there are two equidistant nearest integers.
*/
- GNC_RND_ROUND_HALF_DOWN = 0x05,
+ GNC_HOW_RND_ROUND_HALF_DOWN = 0x05,
/** Round to the nearest integer, rounding away from zero
* when there are two equidistant nearest integers.
*/
- GNC_RND_ROUND_HALF_UP = 0x06,
+ GNC_HOW_RND_ROUND_HALF_UP = 0x06,
/** Use unbiased ("banker's") rounding. This rounds to the
* nearest integer, and to the nearest even integer when there
* are two equidistant nearest integers. This is generally the
* one you should use for financial quantities.
*/
- GNC_RND_ROUND = 0x07,
+ GNC_HOW_RND_ROUND = 0x07,
/** Never round at all, and signal an error if there is a
* fractional result in a computation.
*/
- GNC_RND_NEVER = 0x08
+ GNC_HOW_RND_NEVER = 0x08
};
/** How to compute a denominator, or'ed into the "how" field. */
@@ -362,42 +215,48 @@
* lose any information in the result but also do not want to
* spend any time finding the "best" denominator.
*/
- GNC_DENOM_EXACT = 0x10,
+ GNC_HOW_DENOM_EXACT = 0x10,
/** Reduce the result value by common factor elimination,
* using the smallest possible value for the denominator that
* keeps the correct ratio. The numerator and denominator of
* the result are relatively prime.
*/
- GNC_DENOM_REDUCE = 0x20,
+ GNC_HOW_DENOM_REDUCE = 0x20,
/** Find the least common multiple of the arguments' denominators
* and use that as the denominator of the result.
*/
- GNC_DENOM_LCD = 0x30,
+ GNC_HOW_DENOM_LCD = 0x30,
/** All arguments are required to have the same denominator,
* that denominator is to be used in the output, and an error
* is to be signaled if any argument has a different denominator.
*/
- GNC_DENOM_FIXED = 0x40,
+ GNC_HOW_DENOM_FIXED = 0x40,
/** Round to the number of significant figures given in the rounding
- * instructions by the GNC_DENOM_SIGFIGS () macro.
+ * instructions by the GNC_HOW_DENOM_SIGFIGS () macro.
*/
- GNC_DENOM_SIGFIG = 0x50
+ GNC_HOW_DENOM_SIGFIG = 0x50
};
+/** Build a 'how' value that will generate a denominator that will
+ * keep at least n significant figures in the result.
+ */
+#define GNC_HOW_DENOM_SIGFIGS( n ) ( ((( n ) & 0xff) << 8) | GNC_HOW_DENOM_SIGFIG)
+#define GNC_HOW_GET_SIGFIGS( a ) ( (( a ) & 0xff00 ) >> 8)
+
/** Error codes */
typedef enum {
GNC_ERROR_OK = 0, /**< No error */
GNC_ERROR_ARG = -1, /**< Argument is not a valid number */
GNC_ERROR_OVERFLOW = -2, /**< Intermediate result overflow */
- /** GNC_DENOM_FIXED was specified, but argument denominators differed. */
+ /** GNC_HOW_DENOM_FIXED was specified, but argument denominators differed. */
GNC_ERROR_DENOM_DIFF = -3,
- /** GNC_RND_NEVER was specified, but the result could not be
+ /** GNC_HOW_RND_NEVER was specified, but the result could not be
* converted to the desired denominator without a remainder. */
GNC_ERROR_REMAINDER = -4
} GNCNumericErrorCode;
@@ -417,50 +276,61 @@
/** Use the value @code{1/n} as the denominator of the output value. */
#define GNC_DENOM_RECIPROCAL( a ) (- ( a ))
-/** Use a value for the denominator that will keep at least n
- * significant figures in the result.
- */
-#define GNC_DENOM_SIGFIGS( n ) ( ((( n ) & 0xff) << 8) | GNC_DENOM_SIGFIG)
-#define GNC_NUMERIC_GET_SIGFIGS( a ) ( (( a ) & 0xff00 ) >> 8)
+/** @} */
-/** @name Constructors */
-/*@{*/
-/** make a gnc_numeric from numerator and denominator */
-gnc_numeric gnc_numeric_create(gint64 num, gint64 denom);
+/** @name Constructors
+ @{*/
+/** Make a gnc_numeric from numerator and denominator */
+static inline
+gnc_numeric gnc_numeric_create(gint64 num, gint64 denom) {
+ gnc_numeric out;
+ out.num = num;
+ out.denom = denom;
+ return out;
+}
/** create a zero-value gnc_numeric */
-gnc_numeric gnc_numeric_zero(void);
+static inline
+gnc_numeric gnc_numeric_zero(void) { return gnc_numeric_create(0, 1); }
-/** convert from floating-point values */
+/** Convert a floating-point number to a gnc_numeric.
+ * Both @var{denom} and @var{how} are used as in arithmetic,
+ * but @code{GNC_DENOM_AUTO} is not recognized; a denominator
+ * must be specified either explicitctly or through sigfigs.
+ */
gnc_numeric double_to_gnc_numeric(double in, gint64 denom,
gint how);
-/** Read a gnc_numeric from str, skipping any leading whitespace, and
- returning a pointer to just past the last byte read. Return NULL
- on error. */
+/** Read a gnc_numeric from str, skipping any leading whitespace,
+ * and return a pointer to just past the last byte read.
+ * Return NULL on error. */
const gchar *string_to_gnc_numeric(const gchar* str, gnc_numeric *n);
-/** make a special error-signalling gnc_numeric */
+/** Create a gnc_numeric object that signals the error condition
+ * noted by @var{error_code}, rather than a number.
+ */
gnc_numeric gnc_numeric_error(GNCNumericErrorCode error_code);
/*@}*/
/** @name Value accessors */
-/*@{*/
-/** Get parts */
-gint64 gnc_numeric_num(gnc_numeric a);
-/** Get parts */
-gint64 gnc_numeric_denom(gnc_numeric a);
+/** @{*/
+/** Return numerator */
+static inline
+gint64 gnc_numeric_num(gnc_numeric a) { return a.num; }
+/** Return denominator */
+static inline
+gint64 gnc_numeric_denom(gnc_numeric a) { return a.denom; }
-/** Convert to floating-point values */
+/** Convert numeric to floating-point value. */
double gnc_numeric_to_double(gnc_numeric in);
/** Convert to string. The returned buffer is to be g_free'd by the
- * caller (it was allocated through g_strdup) */
+ * caller (it was allocated through g_strdup) */
gchar *gnc_numeric_to_string(gnc_numeric n);
/*@}*/
/** @name Tests */
-/*@{*/
+/** @{*/
/** Check for error signal in value. Returns GNC_ERROR_OK (==0) if
* the number appears to be valid, otherwise it returns the
* type of error. Error values always have a denominator of zero.
@@ -479,29 +349,42 @@
/** Returns 1 if @var{a} > 0, otherwise returns 0. */
gboolean gnc_numeric_positive_p(gnc_numeric a);
-/** Equivalence predicate: Returns TRUE (1) if a and b are exactly the
- * same (same numerator and denominator)
+/** Equivalence predicate: Returns TRUE (1) if a and b are
+ * exactly the same (have the same numerator and denominator)
*/
gboolean gnc_numeric_eq(gnc_numeric a, gnc_numeric b);
/** Equivalence predicate: Returns TRUE (1) if a and b represent
- * exactly the same number (ratio of numerator to denominator is
- * exactly equal)
+ * the same number. That is, return TRUE if the ratios, when
+ * reduced by eliminating common factors, are identical.
*/
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b);
-/** Equivalence predicate: Returns TRUE (1) if after both are
- * converted to DENOM using method HOW, a and b are
- * gnc_numeric_equal().
+/** Equivalence predicate:
+ * Convert both @var{a} and @var{b} to @var{denom} using the
+ * specified DENOM and method HOW, and compare numerators
+ * the results using gnc_numeric_equal.
+ *
+ at example
+ For example, if @code{@var{a} == 7/16} and @code{@var{b} == 3/4},
+ @code{gnc_numeric_same(@var{a}, @var{b}, 2, GNC_HOW_RND_TRUNC) == 1}
+ because both 7/16 and 3/4 round to 1/2 under truncation. However,
+ @code{gnc_numeric_same(@var{a}, @var{b}, 2, GNC_HOW_RND_ROUND) == 0}
+ because 7/16 rounds to 1/2 under unbiased rounding but 3/4 rounds
+ to 2/2.
+ at end example
*/
int gnc_numeric_same(gnc_numeric a, gnc_numeric b,
gint64 denom, gint how);
/*@}*/
/** @name Arithmetic operations */
-/*@{*/
+/** @{*/
+/** Return a+b. */
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b,
gint64 denom, gint how);
+
+/** Return a-b. */
gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b,
gint64 denom, gint how);
@@ -530,30 +413,35 @@
/**
* Shortcut for common case: gnc_numeric_add(a, b, GNC_DENOM_AUTO,
- * GNC_DENOM_FIXED | GNC_RND_NEVER);
+ * GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
*/
static inline
gnc_numeric gnc_numeric_add_fixed(gnc_numeric a, gnc_numeric b) {
return gnc_numeric_add(a, b, GNC_DENOM_AUTO,
- GNC_DENOM_FIXED | GNC_RND_NEVER);
+ GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
}
/**
* Shortcut for most common case: gnc_numeric_sub(a, b, GNC_DENOM_AUTO,
- * GNC_DENOM_FIXED | GNC_RND_NEVER);
+ * GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
*/
static inline
gnc_numeric gnc_numeric_sub_fixed(gnc_numeric a, gnc_numeric b) {
return gnc_numeric_sub(a, b, GNC_DENOM_AUTO,
- GNC_DENOM_FIXED | GNC_RND_NEVER);
+ GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
}
/*@}*/
/** @name Arithmetic functions with exact error returns */
-/*@{*/
+/** @{*/
+/** The same as gnc_numeric_add, but uses @var{error} for accumulating
+ * conversion roundoff error. */
gnc_numeric gnc_numeric_add_with_error(gnc_numeric a, gnc_numeric b,
gint64 denom, gint how,
gnc_numeric * error);
+
+/** The same as gnc_numeric_sub, but uses @var{error} for accumulating
+ * conversion roundoff error. */
gnc_numeric gnc_numeric_sub_with_error(gnc_numeric a, gnc_numeric b,
gint64 denom, gint how,
gnc_numeric * error);
@@ -564,18 +452,27 @@
gnc_numeric gnc_numeric_mul_with_error(gnc_numeric a, gnc_numeric b,
gint64 denom, gint how,
gnc_numeric * error);
+
+/** The same as @code{gnc_numeric_div}, but uses @var{error} for
+ * accumulating conversion roundoff error.
+ */
gnc_numeric gnc_numeric_div_with_error(gnc_numeric a, gnc_numeric b,
gint64 denom, gint how,
gnc_numeric * error);
/*@}*/
/** @name Change denominator */
-/*@{*/
-/** change the denominator of a gnc_numeric value */
+/** @{*/
+/** Change the denominator of a gnc_numeric value to the
+ * specified denominator under standard arguments
+ * @var{denom} and @var{how}.
+ */
gnc_numeric gnc_numeric_convert(gnc_numeric in, gint64 denom,
gint how);
-/** change the denominator of a gnc_numeric value */
+/** Same as @code{gnc_numeric_convert}, but return a remainder
+ * value for accumulating conversion error.
+*/
gnc_numeric gnc_numeric_convert_with_error(gnc_numeric in, gint64 denom,
gint how,
gnc_numeric * error);
@@ -585,7 +482,22 @@
gnc_numeric gnc_numeric_reduce(gnc_numeric in);
/*@}*/
+/** Deprecated, backwards-compate definitions */
+#define GNC_RND_FLOOR GNC_HOW_RND_FLOOR
+#define GNC_RND_CEIL GNC_HOW_RND_CEIL
+#define GNC_RND_TRUNC GNC_HOW_RND_TRUNC
+#define GNC_RND_PROMOTE GNC_HOW_RND_PROMOTE
+#define GNC_RND_ROUND_HALF_DOWN GNC_HOW_RND_ROUND_HALF_DOWN
+#define GNC_RND_ROUND_HALF_UP GNC_HOW_RND_ROUND_HALF_UP
+#define GNC_RND_ROUND GNC_HOW_RND_ROUND
+#define GNC_RND_NEVER GNC_HOW_RND_NEVER
+
+#define GNC_DENOM_EXACT GNC_HOW_DENOM_EXACT
+#define GNC_DENOM_REDUCE GNC_HOW_DENOM_REDUCE
+#define GNC_DENOM_LCD GNC_HOW_DENOM_LCD
+#define GNC_DENOM_FIXED GNC_HOW_DENOM_FIXED
+#define GNC_DENOM_SIGFIG GNC_HOW_DENOM_SIGFIG
+#define GNC_DENOM_SIGFIGS(X) GNC_HOW_DENOM_SIGFIGS(X)
+#define GNC_NUMERIC_GET_SIGFIGS(X) GNC_HOW_GET_SIGFIGS(X)
#endif
-
-/*@}*/
More information about the gnucash-changes
mailing list