|
GnuCash 2.4.99
|
00001 /******************************************************************** 00002 * gnc-numeric.h - A rational number library * 00003 * This program is free software; you can redistribute it and/or * 00004 * modify it under the terms of the GNU General Public License as * 00005 * published by the Free Software Foundation; either version 2 of * 00006 * the License, or (at your option) any later version. * 00007 * * 00008 * This program is distributed in the hope that it will be useful, * 00009 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00011 * GNU General Public License for more details. * 00012 * * 00013 * You should have received a copy of the GNU General Public License* 00014 * along with this program; if not, contact: * 00015 * * 00016 * Free Software Foundation Voice: +1-617-542-5942 * 00017 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * 00018 * Boston, MA 02110-1301, USA gnu@gnu.org * 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 00123 #define GNC_NUMERIC_RND_MASK 0x0000000f 00124 #define GNC_NUMERIC_DENOM_MASK 0x000000f0 00125 #define GNC_NUMERIC_SIGFIGS_MASK 0x0000ff00 00126 00140 enum 00141 { 00143 GNC_HOW_RND_FLOOR = 0x01, 00144 00146 GNC_HOW_RND_CEIL = 0x02, 00147 00149 GNC_HOW_RND_TRUNC = 0x03, 00150 00152 GNC_HOW_RND_PROMOTE = 0x04, 00153 00157 GNC_HOW_RND_ROUND_HALF_DOWN = 0x05, 00158 00162 GNC_HOW_RND_ROUND_HALF_UP = 0x06, 00163 00169 GNC_HOW_RND_ROUND = 0x07, 00170 00174 GNC_HOW_RND_NEVER = 0x08 00175 }; 00176 00178 enum 00179 { 00185 GNC_HOW_DENOM_EXACT = 0x10, 00186 00192 GNC_HOW_DENOM_REDUCE = 0x20, 00193 00197 GNC_HOW_DENOM_LCD = 0x30, 00198 00203 GNC_HOW_DENOM_FIXED = 0x40, 00204 00208 GNC_HOW_DENOM_SIGFIG = 0x50 00209 }; 00210 00214 #define GNC_HOW_DENOM_SIGFIGS( n ) ( ((( n ) & 0xff) << 8) | GNC_HOW_DENOM_SIGFIG) 00215 #define GNC_HOW_GET_SIGFIGS( a ) ( (( a ) & 0xff00 ) >> 8) 00216 00218 typedef enum 00219 { 00220 GNC_ERROR_OK = 0, 00221 GNC_ERROR_ARG = -1, 00222 GNC_ERROR_OVERFLOW = -2, 00225 GNC_ERROR_DENOM_DIFF = -3, 00226 00229 GNC_ERROR_REMAINDER = -4 00230 } GNCNumericErrorCode; 00231 00232 00242 #define GNC_DENOM_AUTO 0 00243 00245 #define GNC_DENOM_RECIPROCAL( a ) (- ( a )) 00246 00254 static inline 00255 gnc_numeric gnc_numeric_create(gint64 num, gint64 denom) 00256 { 00257 gnc_numeric out; 00258 out.num = num; 00259 out.denom = denom; 00260 return out; 00261 } 00262 00264 static inline 00265 gnc_numeric gnc_numeric_zero(void) 00266 { 00267 return gnc_numeric_create(0, 1); 00268 } 00269 00294 gnc_numeric double_to_gnc_numeric(double n, gint64 denom, 00295 gint how); 00296 00300 gboolean string_to_gnc_numeric(const gchar* str, gnc_numeric *n); 00301 00305 gnc_numeric gnc_numeric_error(GNCNumericErrorCode error_code); 00306 00309 const char* gnc_numeric_errorCode_to_string(GNCNumericErrorCode error_code); 00316 static inline 00317 gint64 gnc_numeric_num(gnc_numeric a) 00318 { 00319 return a.num; 00320 } 00322 static inline 00323 gint64 gnc_numeric_denom(gnc_numeric a) 00324 { 00325 return a.denom; 00326 } 00327 00329 gdouble gnc_numeric_to_double(gnc_numeric n); 00330 00333 gchar *gnc_numeric_to_string(gnc_numeric n); 00334 00337 gchar * gnc_num_dbg_to_string(gnc_numeric n); 00347 GNCNumericErrorCode gnc_numeric_check(gnc_numeric a); 00348 00350 gint gnc_numeric_compare(gnc_numeric a, gnc_numeric b); 00351 00353 gboolean gnc_numeric_zero_p(gnc_numeric a); 00354 00356 gboolean gnc_numeric_negative_p(gnc_numeric a); 00357 00359 gboolean gnc_numeric_positive_p(gnc_numeric a); 00360 00364 gboolean gnc_numeric_eq(gnc_numeric a, gnc_numeric b); 00365 00370 gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b); 00371 00384 gint gnc_numeric_same(gnc_numeric a, gnc_numeric b, 00385 gint64 denom, gint how); 00392 gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, 00393 gint64 denom, gint how); 00394 00396 gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b, 00397 gint64 denom, gint how); 00398 00404 gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, 00405 gint64 denom, gint how); 00406 00414 gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y, 00415 gint64 denom, gint how); 00419 gnc_numeric gnc_numeric_neg(gnc_numeric a); 00420 00424 gnc_numeric gnc_numeric_abs(gnc_numeric a); 00425 00430 static inline 00431 gnc_numeric gnc_numeric_add_fixed(gnc_numeric a, gnc_numeric b) 00432 { 00433 return gnc_numeric_add(a, b, GNC_DENOM_AUTO, 00434 GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER); 00435 } 00436 00441 static inline 00442 gnc_numeric gnc_numeric_sub_fixed(gnc_numeric a, gnc_numeric b) 00443 { 00444 return gnc_numeric_sub(a, b, GNC_DENOM_AUTO, 00445 GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER); 00446 } 00454 gnc_numeric gnc_numeric_add_with_error(gnc_numeric a, gnc_numeric b, 00455 gint64 denom, gint how, 00456 gnc_numeric * error); 00457 00460 gnc_numeric gnc_numeric_sub_with_error(gnc_numeric a, gnc_numeric b, 00461 gint64 denom, gint how, 00462 gnc_numeric * error); 00463 00467 gnc_numeric gnc_numeric_mul_with_error(gnc_numeric a, gnc_numeric b, 00468 gint64 denom, gint how, 00469 gnc_numeric * error); 00470 00474 gnc_numeric gnc_numeric_div_with_error(gnc_numeric a, gnc_numeric b, 00475 gint64 denom, gint how, 00476 gnc_numeric * error); 00486 gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, 00487 gint how); 00488 00489 #if 0 00490 /* Implementation missing! */ 00491 /* Same as gnc_numeric_convert, but return a remainder 00492 * value for accumulating conversion error. 00493 */ 00494 gnc_numeric gnc_numeric_convert_with_error(gnc_numeric n, gint64 denom, 00495 gint how, 00496 gnc_numeric * error); 00497 #endif 00498 00501 gnc_numeric gnc_numeric_reduce(gnc_numeric n); 00502 00515 gboolean gnc_numeric_to_decimal(gnc_numeric * a, 00516 guint8 * max_decimal_places); 00522 GType gnc_numeric_get_type( void ); 00523 #define GNC_TYPE_NUMERIC (gnc_numeric_get_type ()) 00524 00527 #endif
1.7.4