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 struct _gnc_numeric
00054 {
00055 gint64 num;
00056 gint64 denom;
00057 };
00058
00062 typedef struct _gnc_numeric gnc_numeric;
00063
00117 #define GNC_NUMERIC_RND_MASK 0x0000000f
00118 #define GNC_NUMERIC_DENOM_MASK 0x000000f0
00119 #define GNC_NUMERIC_SIGFIGS_MASK 0x0000ff00
00120
00130 enum
00131 {
00133 GNC_HOW_RND_FLOOR = 0x01,
00134
00136 GNC_HOW_RND_CEIL = 0x02,
00137
00139 GNC_HOW_RND_TRUNC = 0x03,
00140
00142 GNC_HOW_RND_PROMOTE = 0x04,
00143
00147 GNC_HOW_RND_ROUND_HALF_DOWN = 0x05,
00148
00152 GNC_HOW_RND_ROUND_HALF_UP = 0x06,
00153
00159 GNC_HOW_RND_ROUND = 0x07,
00160
00164 GNC_HOW_RND_NEVER = 0x08
00165 };
00166
00168 enum
00169 {
00175 GNC_HOW_DENOM_EXACT = 0x10,
00176
00182 GNC_HOW_DENOM_REDUCE = 0x20,
00183
00187 GNC_HOW_DENOM_LCD = 0x30,
00188
00193 GNC_HOW_DENOM_FIXED = 0x40,
00194
00198 GNC_HOW_DENOM_SIGFIG = 0x50
00199 };
00200
00204 #define GNC_HOW_DENOM_SIGFIGS( n ) ( ((( n ) & 0xff) << 8) | GNC_HOW_DENOM_SIGFIG)
00205 #define GNC_HOW_GET_SIGFIGS( a ) ( (( a ) & 0xff00 ) >> 8)
00206
00208 typedef enum
00209 {
00210 GNC_ERROR_OK = 0,
00211 GNC_ERROR_ARG = -1,
00212 GNC_ERROR_OVERFLOW = -2,
00215 GNC_ERROR_DENOM_DIFF = -3,
00216
00219 GNC_ERROR_REMAINDER = -4
00220 } GNCNumericErrorCode;
00221
00222
00232 #define GNC_DENOM_AUTO 0
00233
00235 #define GNC_DENOM_RECIPROCAL( a ) (- ( a ))
00236
00243 static inline gnc_numeric
00244 gnc_numeric_create (gint64 num, gint64 denom)
00245 {
00246 gnc_numeric out;
00247 out.num = num;
00248 out.denom = denom;
00249 return out;
00250 }
00251
00253 static inline gnc_numeric
00254 gnc_numeric_zero (void)
00255 {
00256 return gnc_numeric_create (0, 1);
00257 }
00258
00264 gnc_numeric double_to_gnc_numeric (double in, gint64 denom, gint how);
00265
00269 gboolean string_to_gnc_numeric (const gchar * str, gnc_numeric * n);
00270
00274 gnc_numeric gnc_numeric_error (GNCNumericErrorCode error_code);
00281 static inline gint64
00282 gnc_numeric_num (gnc_numeric a)
00283 {
00284 return a.num;
00285 }
00286
00288 static inline gint64
00289 gnc_numeric_denom (gnc_numeric a)
00290 {
00291 return a.denom;
00292 }
00293
00295 gdouble gnc_numeric_to_double (gnc_numeric in);
00296
00299 gchar *gnc_numeric_to_string (gnc_numeric n);
00300
00303 gchar *gnc_num_dbg_to_string (gnc_numeric n);
00313 GNCNumericErrorCode gnc_numeric_check (gnc_numeric a);
00314
00316 gint gnc_numeric_compare (gnc_numeric a, gnc_numeric b);
00317
00319 gboolean gnc_numeric_zero_p (gnc_numeric a);
00320
00322 gboolean gnc_numeric_negative_p (gnc_numeric a);
00323
00325 gboolean gnc_numeric_positive_p (gnc_numeric a);
00326
00330 gboolean gnc_numeric_eq (gnc_numeric a, gnc_numeric b);
00331
00336 gboolean gnc_numeric_equal (gnc_numeric a, gnc_numeric b);
00337
00350 gint gnc_numeric_same (gnc_numeric a, gnc_numeric b, gint64 denom, gint how);
00357 gnc_numeric gnc_numeric_add (gnc_numeric a, gnc_numeric b,
00358 gint64 denom, gint how);
00359
00361 gnc_numeric gnc_numeric_sub (gnc_numeric a, gnc_numeric b,
00362 gint64 denom, gint how);
00363
00369 gnc_numeric gnc_numeric_mul (gnc_numeric a, gnc_numeric b,
00370 gint64 denom, gint how);
00371
00379 gnc_numeric gnc_numeric_div (gnc_numeric x, gnc_numeric y,
00380 gint64 denom, gint how);
00382 gnc_numeric gnc_numeric_neg (gnc_numeric a);
00383
00385 gnc_numeric gnc_numeric_abs (gnc_numeric a);
00386
00391 static inline gnc_numeric
00392 gnc_numeric_add_fixed (gnc_numeric a, gnc_numeric b)
00393 {
00394 return gnc_numeric_add (a, b, GNC_DENOM_AUTO,
00395 GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
00396 }
00397
00402 static inline gnc_numeric
00403 gnc_numeric_sub_fixed (gnc_numeric a, gnc_numeric b)
00404 {
00405 return gnc_numeric_sub (a, b, GNC_DENOM_AUTO,
00406 GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
00407 }
00408
00416 gnc_numeric gnc_numeric_add_with_error (gnc_numeric a, gnc_numeric b,
00417 gint64 denom, gint how,
00418 gnc_numeric * error);
00419
00422 gnc_numeric gnc_numeric_sub_with_error (gnc_numeric a, gnc_numeric b,
00423 gint64 denom, gint how,
00424 gnc_numeric * error);
00425
00429 gnc_numeric gnc_numeric_mul_with_error (gnc_numeric a, gnc_numeric b,
00430 gint64 denom, gint how,
00431 gnc_numeric * error);
00432
00436 gnc_numeric gnc_numeric_div_with_error (gnc_numeric a, gnc_numeric b,
00437 gint64 denom, gint how,
00438 gnc_numeric * error);
00448 gnc_numeric gnc_numeric_convert (gnc_numeric in, gint64 denom, gint how);
00449
00453 gnc_numeric gnc_numeric_convert_with_error (gnc_numeric in, gint64 denom,
00454 gint how, gnc_numeric * error);
00455
00458 gnc_numeric gnc_numeric_reduce (gnc_numeric in);
00464 #define GNC_RND_FLOOR GNC_HOW_RND_FLOOR
00465 #define GNC_RND_CEIL GNC_HOW_RND_CEIL
00466 #define GNC_RND_TRUNC GNC_HOW_RND_TRUNC
00467 #define GNC_RND_PROMOTE GNC_HOW_RND_PROMOTE
00468 #define GNC_RND_ROUND_HALF_DOWN GNC_HOW_RND_ROUND_HALF_DOWN
00469 #define GNC_RND_ROUND_HALF_UP GNC_HOW_RND_ROUND_HALF_UP
00470 #define GNC_RND_ROUND GNC_HOW_RND_ROUND
00471 #define GNC_RND_NEVER GNC_HOW_RND_NEVER
00472
00473 #define GNC_DENOM_EXACT GNC_HOW_DENOM_EXACT
00474 #define GNC_DENOM_REDUCE GNC_HOW_DENOM_REDUCE
00475 #define GNC_DENOM_LCD GNC_HOW_DENOM_LCD
00476 #define GNC_DENOM_FIXED GNC_HOW_DENOM_FIXED
00477 #define GNC_DENOM_SIGFIG GNC_HOW_DENOM_SIGFIG
00478
00479 #define GNC_DENOM_SIGFIGS(X) GNC_HOW_DENOM_SIGFIGS(X)
00480 #define GNC_NUMERIC_GET_SIGFIGS(X) GNC_HOW_GET_SIGFIGS(X)
00481
00483 #endif