GnuCash 2.4.99
gnc-numeric.h
Go to the documentation of this file.
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
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines