00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00050 #ifndef GNC_NUMERIC_H
00051 #define GNC_NUMERIC_H
00052
00053 #include <glib-object.h>
00054
00055 struct _gnc_numeric
00056 {
00057 gint64 num;
00058 gint64 denom;
00059 };
00060
00064 typedef struct _gnc_numeric gnc_numeric;
00065
00119 #define GNC_NUMERIC_RND_MASK 0x0000000f
00120 #define GNC_NUMERIC_DENOM_MASK 0x000000f0
00121 #define GNC_NUMERIC_SIGFIGS_MASK 0x0000ff00
00122
00132 enum
00133 {
00135 GNC_HOW_RND_FLOOR = 0x01,
00136
00138 GNC_HOW_RND_CEIL = 0x02,
00139
00141 GNC_HOW_RND_TRUNC = 0x03,
00142
00144 GNC_HOW_RND_PROMOTE = 0x04,
00145
00149 GNC_HOW_RND_ROUND_HALF_DOWN = 0x05,
00150
00154 GNC_HOW_RND_ROUND_HALF_UP = 0x06,
00155
00161 GNC_HOW_RND_ROUND = 0x07,
00162
00166 GNC_HOW_RND_NEVER = 0x08
00167 };
00168
00170 enum
00171 {
00177 GNC_HOW_DENOM_EXACT = 0x10,
00178
00184 GNC_HOW_DENOM_REDUCE = 0x20,
00185
00189 GNC_HOW_DENOM_LCD = 0x30,
00190
00195 GNC_HOW_DENOM_FIXED = 0x40,
00196
00200 GNC_HOW_DENOM_SIGFIG = 0x50
00201 };
00202
00206 #define GNC_HOW_DENOM_SIGFIGS( n ) ( ((( n ) & 0xff) << 8) | GNC_HOW_DENOM_SIGFIG)
00207 #define GNC_HOW_GET_SIGFIGS( a ) ( (( a ) & 0xff00 ) >> 8)
00208
00210 typedef enum
00211 {
00212 GNC_ERROR_OK = 0,
00213 GNC_ERROR_ARG = -1,
00214 GNC_ERROR_OVERFLOW = -2,
00217 GNC_ERROR_DENOM_DIFF = -3,
00218
00221 GNC_ERROR_REMAINDER = -4
00222 } GNCNumericErrorCode;
00223
00224
00234 #define GNC_DENOM_AUTO 0
00235
00237 #define GNC_DENOM_RECIPROCAL( a ) (- ( a ))
00238
00245 static inline
00246 gnc_numeric gnc_numeric_create(gint64 num, gint64 denom)
00247 {
00248 gnc_numeric out;
00249 out.num = num;
00250 out.denom = denom;
00251 return out;
00252 }
00253
00255 static inline
00256 gnc_numeric gnc_numeric_zero(void)
00257 {
00258 return gnc_numeric_create(0, 1);
00259 }
00260
00266 gnc_numeric double_to_gnc_numeric(double n, gint64 denom,
00267 gint how);
00268
00272 gboolean string_to_gnc_numeric(const gchar* str, gnc_numeric *n);
00273
00277 gnc_numeric gnc_numeric_error(GNCNumericErrorCode error_code);
00278
00281 const char* gnc_numeric_errorCode_to_string(GNCNumericErrorCode error_code);
00288 static inline
00289 gint64 gnc_numeric_num(gnc_numeric a)
00290 {
00291 return a.num;
00292 }
00294 static inline
00295 gint64 gnc_numeric_denom(gnc_numeric a)
00296 {
00297 return a.denom;
00298 }
00299
00301 gdouble gnc_numeric_to_double(gnc_numeric n);
00302
00305 gchar *gnc_numeric_to_string(gnc_numeric n);
00306
00309 gchar * gnc_num_dbg_to_string(gnc_numeric n);
00319 GNCNumericErrorCode gnc_numeric_check(gnc_numeric a);
00320
00322 gint gnc_numeric_compare(gnc_numeric a, gnc_numeric b);
00323
00325 gboolean gnc_numeric_zero_p(gnc_numeric a);
00326
00328 gboolean gnc_numeric_negative_p(gnc_numeric a);
00329
00331 gboolean gnc_numeric_positive_p(gnc_numeric a);
00332
00336 gboolean gnc_numeric_eq(gnc_numeric a, gnc_numeric b);
00337
00342 gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b);
00343
00356 gint gnc_numeric_same(gnc_numeric a, gnc_numeric b,
00357 gint64 denom, gint how);
00364 gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b,
00365 gint64 denom, gint how);
00366
00368 gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b,
00369 gint64 denom, gint how);
00370
00376 gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b,
00377 gint64 denom, gint how);
00378
00386 gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y,
00387 gint64 denom, gint how);
00389 gnc_numeric gnc_numeric_neg(gnc_numeric a);
00390
00392 gnc_numeric gnc_numeric_abs(gnc_numeric a);
00393
00398 static inline
00399 gnc_numeric gnc_numeric_add_fixed(gnc_numeric a, gnc_numeric b)
00400 {
00401 return gnc_numeric_add(a, b, GNC_DENOM_AUTO,
00402 GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
00403 }
00404
00409 static inline
00410 gnc_numeric gnc_numeric_sub_fixed(gnc_numeric a, gnc_numeric b)
00411 {
00412 return gnc_numeric_sub(a, b, GNC_DENOM_AUTO,
00413 GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
00414 }
00422 gnc_numeric gnc_numeric_add_with_error(gnc_numeric a, gnc_numeric b,
00423 gint64 denom, gint how,
00424 gnc_numeric * error);
00425
00428 gnc_numeric gnc_numeric_sub_with_error(gnc_numeric a, gnc_numeric b,
00429 gint64 denom, gint how,
00430 gnc_numeric * error);
00431
00435 gnc_numeric gnc_numeric_mul_with_error(gnc_numeric a, gnc_numeric b,
00436 gint64 denom, gint how,
00437 gnc_numeric * error);
00438
00442 gnc_numeric gnc_numeric_div_with_error(gnc_numeric a, gnc_numeric b,
00443 gint64 denom, gint how,
00444 gnc_numeric * error);
00454 gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom,
00455 gint how);
00456
00457 #if 0
00458
00459
00460
00461
00462 gnc_numeric gnc_numeric_convert_with_error(gnc_numeric n, gint64 denom,
00463 gint how,
00464 gnc_numeric * error);
00465 #endif
00466
00469 gnc_numeric gnc_numeric_reduce(gnc_numeric n);
00470
00483 gboolean gnc_numeric_to_decimal(gnc_numeric * a,
00484 guint8 * max_decimal_places);
00490 GType gnc_numeric_get_type( void );
00491 #define GNC_TYPE_NUMERIC (gnc_numeric_get_type ())
00492
00495 #endif