00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00049 #ifndef QOF_NUMERIC_H
00050 #define QOF_NUMERIC_H
00051
00052 struct _QofNumeric
00053 {
00054 gint64 num;
00055 gint64 denom;
00056 };
00057
00061 typedef struct _QofNumeric QofNumeric;
00062
00116 #define QOF_NUMERIC_RND_MASK 0x0000000f
00117 #define QOF_NUMERIC_DENOM_MASK 0x000000f0
00118 #define QOF_NUMERIC_SIGFIGS_MASK 0x0000ff00
00119
00129 enum
00130 {
00132 QOF_HOW_RND_FLOOR = 0x01,
00133
00135 QOF_HOW_RND_CEIL = 0x02,
00136
00138 QOF_HOW_RND_TRUNC = 0x03,
00139
00141 QOF_HOW_RND_PROMOTE = 0x04,
00142
00146 QOF_HOW_RND_ROUND_HALF_DOWN = 0x05,
00147
00151 QOF_HOW_RND_ROUND_HALF_UP = 0x06,
00152
00158 QOF_HOW_RND_ROUND = 0x07,
00159
00163 QOF_HOW_RND_NEVER = 0x08
00164 };
00165
00167 enum
00168 {
00174 QOF_HOW_DENOM_EXACT = 0x10,
00175
00181 QOF_HOW_DENOM_REDUCE = 0x20,
00182
00186 QOF_HOW_DENOM_LCD = 0x30,
00187
00192 QOF_HOW_DENOM_FIXED = 0x40,
00193
00197 QOF_HOW_DENOM_SIGFIG = 0x50
00198 };
00199
00203 #define QOF_HOW_DENOM_SIGFIGS( n ) ( ((( n ) & 0xff) << 8) | QOF_HOW_DENOM_SIGFIG)
00204 #define QOF_HOW_GET_SIGFIGS( a ) ( (( a ) & 0xff00 ) >> 8)
00205
00207 typedef enum
00208 {
00209 QOF_ERROR_OK = 0,
00210 QOF_ERROR_ARG = -1,
00211 QOF_ERROR_OVERFLOW = -2,
00214 QOF_ERROR_DENOM_DIFF = -3,
00215
00218 QOF_ERROR_REMAINDER = -4
00219 } QofNumericErrorCode;
00220
00221
00231 #define QOF_DENOM_AUTO 0
00232
00234 #define QOF_DENOM_RECIPROCAL( a ) (- ( a ))
00235
00242 static inline QofNumeric
00243 qof_numeric_create (gint64 num, gint64 denom)
00244 {
00245 QofNumeric out;
00246 out.num = num;
00247 out.denom = denom;
00248 return out;
00249 }
00250
00252 static inline QofNumeric
00253 qof_numeric_zero (void)
00254 {
00255 return qof_numeric_create (0, 1);
00256 }
00257
00263 QofNumeric
00264 qof_numeric_from_double (gdouble in, gint64 denom, gint how);
00265
00269 gboolean
00270 qof_numeric_from_string (const gchar * str, QofNumeric * n);
00271
00275 QofNumeric
00276 qof_numeric_error (QofNumericErrorCode error_code);
00283 static inline gint64
00284 qof_numeric_num (QofNumeric a)
00285 {
00286 return a.num;
00287 }
00288
00290 static inline gint64
00291 qof_numeric_denom (QofNumeric a)
00292 {
00293 return a.denom;
00294 }
00295
00297 gdouble
00298 qof_numeric_to_double (QofNumeric in);
00299
00302 gchar *
00303 qof_numeric_to_string (QofNumeric n);
00304
00307 gchar *
00308 qof_numeric_dbg_to_string (QofNumeric n);
00318 QofNumericErrorCode
00319 qof_numeric_check (QofNumeric a);
00320
00322 gint
00323 qof_numeric_compare (QofNumeric a, QofNumeric b);
00324
00326 gboolean
00327 qof_numeric_zero_p (QofNumeric a);
00328
00330 gboolean
00331 qof_numeric_negative_p (QofNumeric a);
00332
00334 gboolean
00335 qof_numeric_positive_p (QofNumeric a);
00336
00340 gboolean
00341 qof_numeric_eq (QofNumeric a, QofNumeric b);
00342
00347 gboolean
00348 qof_numeric_equal (QofNumeric a, QofNumeric b);
00349
00362 gint
00363 qof_numeric_same (QofNumeric a, QofNumeric b, gint64 denom, gint how);
00370 QofNumeric
00371 qof_numeric_add (QofNumeric a, QofNumeric b,
00372 gint64 denom, gint how);
00373
00375 QofNumeric
00376 qof_numeric_sub (QofNumeric a, QofNumeric b,
00377 gint64 denom, gint how);
00378
00384 QofNumeric
00385 qof_numeric_mul (QofNumeric a, QofNumeric b,
00386 gint64 denom, gint how);
00387
00395 QofNumeric
00396 qof_numeric_div (QofNumeric x, QofNumeric y,
00397 gint64 denom, gint how);
00399 QofNumeric
00400 qof_numeric_neg (QofNumeric a);
00401
00403 QofNumeric
00404 qof_numeric_abs (QofNumeric a);
00405
00410 static inline QofNumeric
00411 qof_numeric_add_fixed (QofNumeric a, QofNumeric b)
00412 {
00413 return qof_numeric_add (a, b, QOF_DENOM_AUTO,
00414 QOF_HOW_DENOM_FIXED | QOF_HOW_RND_NEVER);
00415 }
00416
00421 static inline QofNumeric
00422 qof_numeric_sub_fixed (QofNumeric a, QofNumeric b)
00423 {
00424 return qof_numeric_sub (a, b, QOF_DENOM_AUTO,
00425 QOF_HOW_DENOM_FIXED | QOF_HOW_RND_NEVER);
00426 }
00427
00435 QofNumeric
00436 qof_numeric_add_with_error (QofNumeric a, QofNumeric b,
00437 gint64 denom, gint how,
00438 QofNumeric * error);
00439
00442 QofNumeric
00443 qof_numeric_sub_with_error (QofNumeric a, QofNumeric b,
00444 gint64 denom, gint how,
00445 QofNumeric * error);
00446
00450 QofNumeric
00451 qof_numeric_mul_with_error (QofNumeric a, QofNumeric b,
00452 gint64 denom, gint how,
00453 QofNumeric * error);
00454
00458 QofNumeric
00459 qof_numeric_div_with_error (QofNumeric a, QofNumeric b,
00460 gint64 denom, gint how,
00461 QofNumeric * error);
00471 QofNumeric
00472 qof_numeric_convert (QofNumeric in, gint64 denom, gint how);
00473
00477 QofNumeric
00478 qof_numeric_convert_with_error (QofNumeric in, gint64 denom,
00479 gint how, QofNumeric * error);
00480
00483 QofNumeric qof_numeric_reduce (QofNumeric in);
00489 #define QOF_RND_FLOOR QOF_HOW_RND_FLOOR
00490 #define QOF_RND_CEIL QOF_HOW_RND_CEIL
00491 #define QOF_RND_TRUNC QOF_HOW_RND_TRUNC
00492 #define QOF_RND_PROMOTE QOF_HOW_RND_PROMOTE
00493 #define QOF_RND_ROUND_HALF_DOWN QOF_HOW_RND_ROUND_HALF_DOWN
00494 #define QOF_RND_ROUND_HALF_UP QOF_HOW_RND_ROUND_HALF_UP
00495 #define QOF_RND_ROUND QOF_HOW_RND_ROUND
00496 #define QOF_RND_NEVER QOF_HOW_RND_NEVER
00497
00498 #define QOF_DENOM_EXACT QOF_HOW_DENOM_EXACT
00499 #define QOF_DENOM_REDUCE QOF_HOW_DENOM_REDUCE
00500 #define QOF_DENOM_LCD QOF_HOW_DENOM_LCD
00501 #define QOF_DENOM_FIXED QOF_HOW_DENOM_FIXED
00502 #define QOF_DENOM_SIGFIG QOF_HOW_DENOM_SIGFIG
00503
00504 #define QOF_DENOM_SIGFIGS(X) QOF_HOW_DENOM_SIGFIGS(X)
00505 #define QOF_NUMERIC_GET_SIGFIGS(X) QOF_HOW_GET_SIGFIGS(X)
00506
00508 #endif