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 {
00132 GNC_HOW_RND_FLOOR = 0x01,
00133
00135 GNC_HOW_RND_CEIL = 0x02,
00136
00138 GNC_HOW_RND_TRUNC = 0x03,
00139
00141 GNC_HOW_RND_PROMOTE = 0x04,
00142
00146 GNC_HOW_RND_ROUND_HALF_DOWN = 0x05,
00147
00151 GNC_HOW_RND_ROUND_HALF_UP = 0x06,
00152
00158 GNC_HOW_RND_ROUND = 0x07,
00159
00163 GNC_HOW_RND_NEVER = 0x08
00164 };
00165
00167 enum {
00173 GNC_HOW_DENOM_EXACT = 0x10,
00174
00180 GNC_HOW_DENOM_REDUCE = 0x20,
00181
00185 GNC_HOW_DENOM_LCD = 0x30,
00186
00191 GNC_HOW_DENOM_FIXED = 0x40,
00192
00196 GNC_HOW_DENOM_SIGFIG = 0x50
00197 };
00198
00202 #define GNC_HOW_DENOM_SIGFIGS( n ) ( ((( n ) & 0xff) << 8) | GNC_HOW_DENOM_SIGFIG)
00203 #define GNC_HOW_GET_SIGFIGS( a ) ( (( a ) & 0xff00 ) >> 8)
00204
00206 typedef enum {
00207 GNC_ERROR_OK = 0,
00208 GNC_ERROR_ARG = -1,
00209 GNC_ERROR_OVERFLOW = -2,
00212 GNC_ERROR_DENOM_DIFF = -3,
00213
00216 GNC_ERROR_REMAINDER = -4
00217 } GNCNumericErrorCode;
00218
00219
00229 #define GNC_DENOM_AUTO 0
00230
00232 #define GNC_DENOM_RECIPROCAL( a ) (- ( a ))
00233
00240 static inline
00241 gnc_numeric gnc_numeric_create(gint64 num, gint64 denom) {
00242 gnc_numeric out;
00243 out.num = num;
00244 out.denom = denom;
00245 return out;
00246 }
00247
00249 static inline
00250 gnc_numeric gnc_numeric_zero(void) { return gnc_numeric_create(0, 1); }
00251
00257 gnc_numeric double_to_gnc_numeric(double in, gint64 denom,
00258 gint how);
00259
00263 gboolean string_to_gnc_numeric(const gchar* str, gnc_numeric *n);
00264
00268 gnc_numeric gnc_numeric_error(GNCNumericErrorCode error_code);
00275 static inline
00276 gint64 gnc_numeric_num(gnc_numeric a) { return a.num; }
00278 static inline
00279 gint64 gnc_numeric_denom(gnc_numeric a) { return a.denom; }
00280
00282 gdouble gnc_numeric_to_double(gnc_numeric in);
00283
00286 gchar *gnc_numeric_to_string(gnc_numeric n);
00287
00290 gchar * gnc_num_dbg_to_string(gnc_numeric n);
00300 GNCNumericErrorCode gnc_numeric_check(gnc_numeric a);
00301
00303 gint gnc_numeric_compare(gnc_numeric a, gnc_numeric b);
00304
00306 gboolean gnc_numeric_zero_p(gnc_numeric a);
00307
00309 gboolean gnc_numeric_negative_p(gnc_numeric a);
00310
00312 gboolean gnc_numeric_positive_p(gnc_numeric a);
00313
00317 gboolean gnc_numeric_eq(gnc_numeric a, gnc_numeric b);
00318
00323 gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b);
00324
00337 gint gnc_numeric_same(gnc_numeric a, gnc_numeric b,
00338 gint64 denom, gint how);
00345 gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b,
00346 gint64 denom, gint how);
00347
00349 gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b,
00350 gint64 denom, gint how);
00351
00357 gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b,
00358 gint64 denom, gint how);
00359
00367 gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y,
00368 gint64 denom, gint how);
00370 gnc_numeric gnc_numeric_neg(gnc_numeric a);
00371
00373 gnc_numeric gnc_numeric_abs(gnc_numeric a);
00374
00379 static inline
00380 gnc_numeric gnc_numeric_add_fixed(gnc_numeric a, gnc_numeric b) {
00381 return gnc_numeric_add(a, b, GNC_DENOM_AUTO,
00382 GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
00383 }
00384
00389 static inline
00390 gnc_numeric gnc_numeric_sub_fixed(gnc_numeric a, gnc_numeric b) {
00391 return gnc_numeric_sub(a, b, GNC_DENOM_AUTO,
00392 GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
00393 }
00401 gnc_numeric gnc_numeric_add_with_error(gnc_numeric a, gnc_numeric b,
00402 gint64 denom, gint how,
00403 gnc_numeric * error);
00404
00407 gnc_numeric gnc_numeric_sub_with_error(gnc_numeric a, gnc_numeric b,
00408 gint64 denom, gint how,
00409 gnc_numeric * error);
00410
00414 gnc_numeric gnc_numeric_mul_with_error(gnc_numeric a, gnc_numeric b,
00415 gint64 denom, gint how,
00416 gnc_numeric * error);
00417
00421 gnc_numeric gnc_numeric_div_with_error(gnc_numeric a, gnc_numeric b,
00422 gint64 denom, gint how,
00423 gnc_numeric * error);
00433 gnc_numeric gnc_numeric_convert(gnc_numeric in, gint64 denom,
00434 gint how);
00435
00439 gnc_numeric gnc_numeric_convert_with_error(gnc_numeric in, gint64 denom,
00440 gint how,
00441 gnc_numeric * error);
00442
00445 gnc_numeric gnc_numeric_reduce(gnc_numeric in);
00451 #define GNC_RND_FLOOR GNC_HOW_RND_FLOOR
00452 #define GNC_RND_CEIL GNC_HOW_RND_CEIL
00453 #define GNC_RND_TRUNC GNC_HOW_RND_TRUNC
00454 #define GNC_RND_PROMOTE GNC_HOW_RND_PROMOTE
00455 #define GNC_RND_ROUND_HALF_DOWN GNC_HOW_RND_ROUND_HALF_DOWN
00456 #define GNC_RND_ROUND_HALF_UP GNC_HOW_RND_ROUND_HALF_UP
00457 #define GNC_RND_ROUND GNC_HOW_RND_ROUND
00458 #define GNC_RND_NEVER GNC_HOW_RND_NEVER
00459
00460 #define GNC_DENOM_EXACT GNC_HOW_DENOM_EXACT
00461 #define GNC_DENOM_REDUCE GNC_HOW_DENOM_REDUCE
00462 #define GNC_DENOM_LCD GNC_HOW_DENOM_LCD
00463 #define GNC_DENOM_FIXED GNC_HOW_DENOM_FIXED
00464 #define GNC_DENOM_SIGFIG GNC_HOW_DENOM_SIGFIG
00465
00466 #define GNC_DENOM_SIGFIGS(X) GNC_HOW_DENOM_SIGFIGS(X)
00467 #define GNC_NUMERIC_GET_SIGFIGS(X) GNC_HOW_GET_SIGFIGS(X)
00468
00470 #endif