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