1 /********************************************************************
2  * gnc-numeric.h - A rational number library                        *
3  * This program is free software; you can redistribute it and/or    *
4  * modify it under the terms of the GNU General Public License as   *
5  * published by the Free Software Foundation; either version 2 of   *
6  * the License, or (at your option) any later version.              *
7  *                                                                  *
8  * This program is distributed in the hope that it will be useful,  *
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
11  * GNU General Public License for more details.                     *
12  *                                                                  *
13  * You should have received a copy of the GNU General Public License*
14  * along with this program; if not, contact:                        *
15  *                                                                  *
16  * Free Software Foundation           Voice:  +1-617-542-5942       *
17  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
18  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
19  *                                                                  *
20  *******************************************************************/
21 
22 /** @addtogroup Numeric
23 
24     The 'Numeric' functions provide a way of working with rational
25     numbers while maintaining strict control over rounding errors
26     when adding rationals with different denominators.  The Numeric
27     class is primarily used for working with monetary amounts,
28     where the denominator typically represents the smallest fraction
29     of the currency (e.g. pennies, centimes).  The numeric class
30     can handle any fraction (e.g. twelfth's) and is not limited
31     to fractions that are powers of ten.
32 
33     A 'Numeric' value represents a number in rational form, with a
34     64-bit integer as numerator and denominator.  Rationals are
35     ideal for many uses, such as performing exact, roundoff-error-free
36     addition and multiplication, but 64-bit rationals do not have
37     the dynamic range of floating point numbers.
38 
39 See \ref gncnumericexample
40 
41 @{ */
42 /** @file gnc-numeric.h
43     @brief An exact-rational-number library for gnucash.
44 	(to be renamed qofnumeric.h in libqof2)
45     @author Copyright (C) 2000 Bill Gribble
46     @author Copyright (C) 2004 Linas Vepstas <linas@linas.org>
47 */
48 
49 
50 #ifndef GNC_NUMERIC_H
51 #define GNC_NUMERIC_H
52 #ifdef __cplusplus
53 extern "C"
54 {
55 #endif
56 
57 #include <glib-object.h>
58 
59 struct _gnc_numeric
60 {
61     gint64  num;
62     gint64  denom;
63 };
64 
65 /** @brief An rational-number type
66  *
67  * This is a rational number, defined by numerator and denominator. */
68 typedef struct _gnc_numeric gnc_numeric;
69 
70 /** @name Arguments Standard Arguments to most functions
71 
72     Most of the gnc_numeric arithmetic functions take two arguments
73     in addition to their numeric args: 'denom', which is the denominator
74     to use in the output gnc_numeric object, and 'how'. which
75     describes how the arithmetic result is to be converted to that
76     denominator. This combination of output denominator and rounding policy
77     allows the results of financial and other rational computations to be
78     properly rounded to the appropriate units.
79 
80     Watch out: You \e must specify a rounding policy such as
81     GNC_HOW_RND_NEVER, otherwise the fractional part of the input
82     value might silently get discarded!
83 
84     Valid values for denom are:
85     GNC_DENOM_AUTO  -- compute denominator exactly
86     integer n       -- Force the denominator of the result to be this integer
87     GNC_DENOM_RECIPROCAL -- Use 1/n as the denominator (???huh???)
88 
89     Valid values for 'how' are bitwise combinations of zero or one
90     "rounding instructions" with zero or one "denominator types".
91     Valid rounding instructions are:
92         GNC_HOW_RND_FLOOR
93         GNC_HOW_RND_CEIL
94         GNC_HOW_RND_TRUNC
95         GNC_HOW_RND_PROMOTE
96         GNC_HOW_RND_ROUND_HALF_DOWN
97         GNC_HOW_RND_ROUND_HALF_UP
98         GNC_HOW_RND_ROUND
99         GNC_HOW_RND_NEVER
100 
101     The denominator type specifies how to compute a denominator if
102     GNC_DENOM_AUTO is specified as the 'denom'. Valid
103     denominator types are:
104         GNC_HOW_DENOM_EXACT
105         GNC_HOW_DENOM_REDUCE
106         GNC_HOW_DENOM_LCD
107         GNC_HOW_DENOM_FIXED
108         GNC_HOW_DENOM_SIGFIGS(N)
109 
110    To use traditional rational-number operational semantics (all results
111    are exact and are reduced to relatively-prime fractions) pass the
112    argument GNC_DENOM_AUTO as 'denom' and
113    GNC_HOW_DENOM_REDUCE| GNC_HOW_RND_NEVER as 'how'.
114 
115    To enforce strict financial semantics (such that all operands must have
116    the same denominator as each other and as the result), use
117    GNC_DENOM_AUTO as 'denom' and
118    GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER as 'how'.
119 @{
120 */
121 
122 /** \brief bitmasks for HOW flags.
123 
124  * bits 8-15 of 'how' are reserved for the number of significant
125  * digits to use in the output with GNC_HOW_DENOM_SIGFIG
126  */
127 #define GNC_NUMERIC_RND_MASK     0x0000000f
128 #define GNC_NUMERIC_DENOM_MASK   0x000000f0
129 #define GNC_NUMERIC_SIGFIGS_MASK 0x0000ff00
130 
131 /** \brief Rounding/Truncation modes for operations.
132 
133  *  Rounding instructions control how fractional parts in the specified
134  *  denominator affect the result. For example, if a computed result is
135  *  "3/4" but the specified denominator for the return value is 2, should
136  *  the return value be "1/2" or "2/2"?
137  *
138  * Watch out: You \e must specify a rounding policy such as
139  * GNC_HOW_RND_NEVER, otherwise the fractional part of the input value
140  * might silently get discarded!
141  *
142  * Possible rounding instructions are:
143  */
144 enum
145 {
146     /** Round toward -infinity */
147     GNC_HOW_RND_FLOOR            = 0x01,
148 
149     /** Round toward +infinity */
150     GNC_HOW_RND_CEIL             = 0x02,
151 
152     /** Truncate fractions (round toward zero) */
153     GNC_HOW_RND_TRUNC            = 0x03,
154 
155     /** Promote fractions (round away from zero) */
156     GNC_HOW_RND_PROMOTE          = 0x04,
157 
158     /** Round to the nearest integer, rounding toward zero
159      *  when there are two equidistant nearest integers.
160      */
161     GNC_HOW_RND_ROUND_HALF_DOWN  = 0x05,
162 
163     /** Round to the nearest integer, rounding away from zero
164      *  when there are two equidistant nearest integers.
165      */
166     GNC_HOW_RND_ROUND_HALF_UP    = 0x06,
167 
168     /** Use unbiased ("banker's") rounding. This rounds to the
169      *  nearest integer, and to the nearest even integer when there
170      *  are two equidistant nearest integers. This is generally the
171      *  one you should use for financial quantities.
172      */
173     GNC_HOW_RND_ROUND            = 0x07,
174 
175     /** Never round at all, and signal an error if there is a
176      *  fractional result in a computation.
177      */
178     GNC_HOW_RND_NEVER            = 0x08
179 };
180 
181 /** How to compute a denominator, or'ed into the "how" field. */
182 enum
183 {
184     /** Use any denominator which gives an exactly correct ratio of
185      *  numerator to denominator. Use EXACT when you do not wish to
186      *  lose any information in the result but also do not want to
187      *  spend any time finding the "best" denominator.
188      */
189     GNC_HOW_DENOM_EXACT  = 0x10,
190 
191     /** Reduce the result value by common factor elimination,
192      *  using the smallest possible value for the denominator that
193      *  keeps the correct ratio. The numerator and denominator of
194      *  the result are relatively prime.
195      */
196     GNC_HOW_DENOM_REDUCE = 0x20,
197 
198     /** Find the least common multiple of the arguments' denominators
199      *  and use that as the denominator of the result.
200      */
201     GNC_HOW_DENOM_LCD    = 0x30,
202 
203     /** All arguments are required to have the same denominator,
204      *  that denominator is to be used in the output, and an error
205      *  is to be signaled if any argument has a different denominator.
206      */
207     GNC_HOW_DENOM_FIXED  = 0x40,
208 
209     /** Round to the number of significant figures given in the rounding
210      *  instructions by the GNC_HOW_DENOM_SIGFIGS () macro.
211      */
212     GNC_HOW_DENOM_SIGFIG = 0x50
213 };
214 
215 /** Build a 'how' value that will generate a denominator that will
216  *  keep at least n significant figures in the result.
217  */
218 #define GNC_HOW_DENOM_SIGFIGS( n ) ( ((( n ) & 0xff) << 8) | GNC_HOW_DENOM_SIGFIG)
219 #define GNC_HOW_GET_SIGFIGS( a ) ( (( a ) & 0xff00 ) >> 8)
220 
221 /** Error codes */
222 typedef enum
223 {
224     GNC_ERROR_OK         =  0,   /**< No error */
225     GNC_ERROR_ARG        = -1,   /**< Argument is not a valid number */
226     GNC_ERROR_OVERFLOW   = -2,   /**< Intermediate result overflow */
227 
228     /** GNC_HOW_DENOM_FIXED was specified, but argument denominators differed.  */
229     GNC_ERROR_DENOM_DIFF = -3,
230 
231     /** GNC_HOW_RND_NEVER  was specified, but the result could not be
232      *  converted to the desired denominator without a remainder. */
233     GNC_ERROR_REMAINDER  = -4
234 } GNCNumericErrorCode;
235 
236 
237 /** Values that can be passed as the 'denom' argument.
238  *  The include a positive number n to be used as the
239  *  denominator of the output value.  Other possibilities
240  *  include the list below:
241  */
242 
243 /** Compute an appropriate denominator automatically. Flags in
244  *  the 'how' argument will specify how to compute the denominator.
245  */
246 #define GNC_DENOM_AUTO 0
247 
248 /**  @} */
249 
250 /** @name Constructors
251 @{
252 */
253 /** Returns a newly created gnc_numeric with the given numerator and
254  * denominator, that is "num/denom". */
255 static inline
gnc_numeric_create(gint64 num,gint64 denom)256 gnc_numeric gnc_numeric_create(gint64 num, gint64 denom)
257 {
258     gnc_numeric out;
259     out.num = num;
260     out.denom = denom;
261     return out;
262 }
263 
264 /** Returns a newly created gnc_numeric of value zero, that is "0/1". */
265 static inline
gnc_numeric_zero(void)266 gnc_numeric gnc_numeric_zero(void)
267 {
268     return gnc_numeric_create(0, 1);
269 }
270 
271 /** Convert a floating-point number to a gnc_numeric.
272  *
273  * Both 'denom' and 'how' are used as in arithmetic.
274  *
275  * \sa \ref Arguments
276  *
277  * \param n The double value that is converted into a gnc_numeric
278  *
279  * \param denom The denominator of the gnc_numeric return value. If
280  * the 'how' argument contains the GNC_HOW_DENOM_SIGFIG flag, this
281  * value will be ignored.  If GNC_DENOM_AUTO is given an appropriate
282  * power of ten will be used for the denominator (it may be reduced
283  * by rounding if appropriate).
284  *
285  * \param how Describes the rounding policy and output
286  * denominator. Watch out: You must specify a rounding policy such
287  * as GNC_HOW_RND_NEVER, otherwise the fractional part of the input
288  * value is silently discarded! Common values for 'how' are
289  * (GNC_HOW_DENOM_REDUCE|GNC_HOW_RND_NEVER) or
290  * (GNC_HOW_DENOM_FIXED|GNC_HOW_RND_NEVER).
291  *
292  * \return The newly created gnc_numeric rational value.
293  */
294 gnc_numeric double_to_gnc_numeric(double n, gint64 denom,
295                                   gint how);
296 
297 /** Read a gnc_numeric from str, skipping any leading whitespace.
298  *  Return TRUE on success and store the resulting value in "n".
299  *  Return NULL on error. */
300 gboolean string_to_gnc_numeric(const gchar* str, gnc_numeric *n);
301 
302 /** Create a gnc_numeric object that signals the error condition
303  *  noted by error_code, rather than a number.
304  */
305 gnc_numeric gnc_numeric_error(GNCNumericErrorCode error_code);
306 
307 /** Returns a string representation of the given GNCNumericErrorCode.
308  */
309 const char* gnc_numeric_errorCode_to_string(GNCNumericErrorCode error_code);
310 /** @} */
311 
312 /** @name Value Accessors
313  @{
314 */
315 /** Returns the numerator of the given gnc_numeric value. */
316 static inline
gnc_numeric_num(gnc_numeric a)317 gint64 gnc_numeric_num(gnc_numeric a)
318 {
319     return a.num;
320 }
321 /** Returns the denominator of the given gnc_numeric value. */
322 static inline
gnc_numeric_denom(gnc_numeric a)323 gint64 gnc_numeric_denom(gnc_numeric a)
324 {
325     return a.denom;
326 }
327 
328 /** Convert numeric to floating-point value. */
329 gdouble      gnc_numeric_to_double(gnc_numeric n);
330 
331 /** Convert to string. The returned buffer is to be g_free'd by the
332  *  caller (it was allocated through g_strdup) */
333 gchar *gnc_numeric_to_string(gnc_numeric n);
334 
335 /** Convert to string. Uses a static, non-thread-safe buffer.
336  *  For internal use only. */
337 gchar * gnc_num_dbg_to_string(gnc_numeric n);
338 /** @}*/
339 
340 /** @name Comparisons and Predicates
341  @{
342 */
343 /** Check for error signal in value. Returns GNC_ERROR_OK (==0) if
344  *  the number appears to be valid, otherwise it returns the
345  *  type of error.  Error values always have a denominator of zero.
346  */
347 GNCNumericErrorCode  gnc_numeric_check(gnc_numeric a);
348 
349 /** Returns 1 if a>b, -1 if b>a, 0 if a == b  */
350 gint gnc_numeric_compare(gnc_numeric a, gnc_numeric b);
351 
352 /** Returns 1 if the given gnc_numeric is 0 (zero), else returns 0. */
353 gboolean gnc_numeric_zero_p(gnc_numeric a);
354 
355 /** Returns 1 if a < 0, otherwise returns 0. */
356 gboolean gnc_numeric_negative_p(gnc_numeric a);
357 
358 /** Returns 1 if a > 0, otherwise returns 0. */
359 gboolean gnc_numeric_positive_p(gnc_numeric a);
360 
361 /** Equivalence predicate: Returns TRUE (1) if a and b are
362  *  exactly the same (have the same numerator and denominator)
363  */
364 gboolean gnc_numeric_eq(gnc_numeric a, gnc_numeric b);
365 
366 /** Equivalence predicate: Returns TRUE (1) if a and b represent
367  *  the same number.  That is, return TRUE if the ratios, when
368  *  reduced by eliminating common factors, are identical.
369  */
370 gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b);
371 
372 /** Equivalence predicate:
373  *  Convert both a and b to denom using the
374  *  specified DENOM and method HOW, and compare numerators
375  *  the results using gnc_numeric_equal.
376  *
377   For example, if a == 7/16 and b == 3/4,
378   gnc_numeric_same(a, b, 2, GNC_HOW_RND_TRUNC) == 1
379   because both 7/16 and 3/4 round to 1/2 under truncation. However,
380   gnc_numeric_same(a, b, 2, GNC_HOW_RND_ROUND) == 0
381   because 7/16 rounds to 1/2 under unbiased rounding but 3/4 rounds
382   to 2/2.
383  */
384 gint gnc_numeric_same(gnc_numeric a, gnc_numeric b,
385                       gint64 denom, gint how);
386 /** @} */
387 
388 /** @name Arithmetic Operations
389  @{
390 */
391 /** Return a+b. */
392 gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b,
393                             gint64 denom, gint how);
394 
395 /** Return a-b. */
396 gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b,
397                             gint64 denom, gint how);
398 
399 /** Multiply a times b, returning the product.  An overflow
400  *  may occur if the result of the multiplication can't
401  *  be represented as a ratio of 64-bit int's after removing
402  *  common factors.
403  */
404 gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b,
405                             gint64 denom, gint how);
406 
407 /** Division.  Note that division can overflow, in the following
408  *  sense: if we write x=a/b and y=c/d  then x/y = (a*d)/(b*c)
409  *  If, after eliminating all common factors between the numerator
410  *  (a*d) and the denominator (b*c),  then if either the numerator
411  *  and/or the denominator are *still* greater than 2^63, then
412  *  the division has overflowed.
413  */
414 gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y,
415                             gint64 denom, gint how);
416 /** Returns a newly created gnc_numeric that is the negative of the
417  * given gnc_numeric value. For a given gnc_numeric "a/b" the returned
418  * value is "-a/b".  */
419 gnc_numeric gnc_numeric_neg(gnc_numeric a);
420 
421 /** Returns a newly created gnc_numeric that is the absolute value of
422  * the given gnc_numeric value. For a given gnc_numeric "a/b" the
423  * returned value is "|a/b|". */
424 gnc_numeric gnc_numeric_abs(gnc_numeric a);
425 
426 /**
427  * Shortcut for common case: gnc_numeric_add(a, b, GNC_DENOM_AUTO,
428  *                        GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
429  */
430 static inline
gnc_numeric_add_fixed(gnc_numeric a,gnc_numeric b)431 gnc_numeric gnc_numeric_add_fixed(gnc_numeric a, gnc_numeric b)
432 {
433     return gnc_numeric_add(a, b, GNC_DENOM_AUTO,
434                            GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
435 }
436 
437 /**
438  * Shortcut for most common case: gnc_numeric_sub(a, b, GNC_DENOM_AUTO,
439  *                        GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
440  */
441 static inline
gnc_numeric_sub_fixed(gnc_numeric a,gnc_numeric b)442 gnc_numeric gnc_numeric_sub_fixed(gnc_numeric a, gnc_numeric b)
443 {
444     return gnc_numeric_sub(a, b, GNC_DENOM_AUTO,
445                            GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
446 }
447 /** @} */
448 
449 
450 /** @name Change Denominator
451  @{
452 */
453 /** Change the denominator of a gnc_numeric value to the
454  *  specified denominator under standard arguments
455  *  'denom' and 'how'.
456  */
457 gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom,
458                                 gint how);
459 
460 /** Return input after reducing it by Greater Common Factor (GCF)
461  *  elimination */
462 gnc_numeric gnc_numeric_reduce(gnc_numeric n);
463 
464 /** Attempt to convert the denominator to an exact power of ten without
465  *  rounding.
466  *
467  *  @param a the ::gnc_numeric value to convert
468  *
469  *  @param max_decimal_places the number of decimal places of the
470  *  converted value. This parameter may be @c NULL.
471  *
472  *  @return @c TRUE if @a a has been converted or was already decimal.
473  *  Otherwise, @c FALSE is returned and @a a and @a max_decimal_places
474  *  remain unchanged.
475  ********************************************************************/
476 gboolean gnc_numeric_to_decimal(gnc_numeric * a,
477                                 guint8 * max_decimal_places);
478 
479 /** Invert a gnc_numeric.
480  * Much faster than dividing 1 by it.
481  * @param num The number to be inverted
482  * @return a gnc_numeric that is the inverse of num
483  */
484 gnc_numeric gnc_numeric_invert (gnc_numeric num);
485 /** @} */
486 
487 /** @name GValue
488   @{
489 */
490 GType gnc_numeric_get_type( void );
491 #define GNC_TYPE_NUMERIC (gnc_numeric_get_type ())
492 
493 #ifdef __cplusplus
494 }
495 #endif
496 
497 #endif
498