29 #include "cashobjects.h"
30 #include "test-stuff.h"
42 retval = g_strdup_printf(
"<ERROR> [%" G_GINT64_FORMAT
" / %" G_GINT64_FORMAT
"]",
48 retval = g_strdup_printf(
"[%" G_GINT64_FORMAT
" / %" G_GINT64_FORMAT
"]",
57 #define check_unary_op(eq,ex,a,i,e) check_unary_op_r(eq,ex,a,i,e,__LINE__)
66 char *e = gnc_numeric_print (expected);
67 char *r = gnc_numeric_print (actual);
68 char *a = gnc_numeric_print (input);
69 char *str = g_strdup_printf (errmsg, e, r, a);
71 do_test_call (eqtest(expected, actual), str, __FILE__, line);
81 #define check_binary_op(ex,a,ia,ib,e) check_binary_op_r(ex,a,ia,ib,e,__LINE__,gnc_numeric_eq)
82 #define check_binary_op_equal(ex,a,ia,ib,e) check_binary_op_r(ex,a,ia,ib,e,__LINE__,gnc_numeric_equal)
92 char *e = gnc_numeric_print (expected);
93 char *r = gnc_numeric_print (actual);
94 char *a = gnc_numeric_print (input_a);
95 char *b = gnc_numeric_print (input_b);
96 char *str = g_strdup_printf (errmsg, e, r, a, b);
98 do_test_call ((eq)(expected, actual), str, __FILE__, line);
120 check_eq_operator (
void)
141 one = gnc_numeric_create (1, 1);
142 rone = gnc_numeric_create (1000000, 1000000);
146 four = gnc_numeric_create (4, 1);
147 rfour = gnc_numeric_create (480, 120);
151 val = gnc_numeric_create(10023234LL, 334216654LL);
154 gnc_numeric_create (5011617, 167108327),
156 val,
"check_reduce(1) expected %s got %s = reduce(%s)");
158 val = gnc_numeric_create(17474724864LL, 136048896LL);
161 gnc_numeric_create (4 * 17 * 17, 9),
163 val,
"check_reduce(2) expected %s got %s = reduce(%s)");
165 val = gnc_numeric_create(1024LL, 1099511627776LL);
168 gnc_numeric_create (1, 1024 * 1024 * 1024),
170 val,
"check_reduce(3): expected %s got %s = reduce(%s)");
176 check_equality_operator (
void)
180 gint64 f, deno, numer;
189 rbig = gnc_numeric_create (numer, deno);
191 big = gnc_numeric_create (1 << 10, 1);
194 big = gnc_numeric_create (1 << 20, 1 << 10);
197 big = gnc_numeric_create (1 << 30, 1 << 20);
203 rbig = gnc_numeric_create (numer, deno);
205 big = gnc_numeric_create (1 << 30, 1);
210 big = gnc_numeric_create (numer, 1 << 10);
214 big = gnc_numeric_create (numer, 1 << 20);
218 for (i = 0; i < NREPS; i++)
225 if (deno == 0 || mult == 0)
231 val = gnc_numeric_create (numer, deno);
232 mval = gnc_numeric_create (numer * mult, deno * mult);
238 bval, rval, mval,
"expected %s got %s = reduce(%s)");
242 val, mval, mval,
"expected %s = %s");
258 gint64 nn = 1 << (32 - m);
261 val = gnc_numeric_create (2 * nn, 2 * mval.denom);
262 check_unary_op (gnc_numeric_unequal,
263 val, mval, mval,
"expected unequality %s != %s");
272 check_rounding (
void)
276 val = gnc_numeric_create(7, 16);
278 gnc_numeric_create (43, 100),
280 val,
"expected %s got %s = (%s as 100th's floor)");
282 gnc_numeric_create (44, 100),
284 val,
"expected %s got %s = (%s as 100th's ceiling)");
286 gnc_numeric_create (43, 100),
288 val,
"expected %s got %s = (%s as 100th's trunc)");
290 gnc_numeric_create (44, 100),
292 val,
"expected %s got %s = (%s as 100th's round)");
294 val = gnc_numeric_create(1511, 1000);
296 gnc_numeric_create (151, 100),
298 val,
"expected %s got %s = (%s as 100th's round)");
300 val = gnc_numeric_create(1516, 1000);
302 gnc_numeric_create (152, 100),
304 val,
"expected %s got %s = (%s as 100th's round)");
307 val = gnc_numeric_create(1515, 1000);
309 gnc_numeric_create (152, 100),
311 val,
"expected %s got %s = (%s as 100th's round)");
313 val = gnc_numeric_create(1525, 1000);
315 gnc_numeric_create (152, 100),
317 val,
"expected %s got %s = (%s as 100th's round)");
319 val = gnc_numeric_create(1535, 1000);
321 gnc_numeric_create (154, 100),
323 val,
"expected %s got %s = (%s as 100th's round)");
325 val = gnc_numeric_create(1545, 1000);
327 gnc_numeric_create (154, 100),
329 val,
"expected %s got %s = (%s as 100th's round)");
341 gnc_numeric_create (112346, 100000),
346 val,
"expected %s = %s double 6 figs");
349 gnc_numeric_create (112346, 10000000),
354 val,
"expected %s = %s double 6 figs");
357 gnc_numeric_create (112346, 100),
362 val,
"expected %s = %s double 6 figs");
364 gnc_numeric_create (112346, 10000000000LL),
369 val,
"expected %s = %s double 6 figs");
372 do_test ((0.4375 == flo),
"float pt conversion");
386 gnc_numeric_create (-2, 6), c,
387 a,
"expected %s got %s = -(%s)");
390 gnc_numeric_create (-1, 4), d,
391 b,
"expected %s got %s = -(%s)");
398 check_add_subtract (
void)
406 a = gnc_numeric_create(2, 6);
407 b = gnc_numeric_create(1, 4);
410 check_binary_op (gnc_numeric_create(7, 12),
412 a, b,
"expected %s got %s = %s + %s for add exact");
414 check_binary_op (gnc_numeric_create(58, 100),
416 a, b,
"expected %s got %s = %s + %s for add 100ths (banker's)");
418 check_binary_op (gnc_numeric_create(5833, 10000),
422 a, b,
"expected %s got %s = %s + %s for add 4 sig figs");
424 check_binary_op (gnc_numeric_create(583333, 1000000),
428 a, b,
"expected %s got %s = %s + %s for add 6 sig figs");
430 check_binary_op (gnc_numeric_create(1, 12),
432 a, b,
"expected %s got %s = %s - %s for sub exact");
435 check_binary_op (gnc_numeric_create(1, 12),
437 a, b,
"expected %s got %s = %s - %s for sub reduce");
439 check_binary_op (gnc_numeric_create(1, 12),
441 a, b,
"expected %s got %s = %s - %s for sub reduce");
443 check_binary_op (gnc_numeric_create(8, 100),
445 a, b,
"expected %s got %s = %s - %s for sub 100ths (banker's)");
451 z = gnc_numeric_zero();
452 check_binary_op (c, gnc_numeric_add_fixed(z, c),
453 z, c,
"expected %s got %s = %s + %s for add fixed");
455 check_binary_op (d, gnc_numeric_add_fixed(z, d),
456 z, d,
"expected %s got %s = %s + %s for add fixed");
463 check_binary_op (gnc_numeric_create(-7, 12),
465 a, b,
"expected %s got %s = %s + %s for add exact");
467 check_binary_op (gnc_numeric_create(-58, 100),
469 a, b,
"expected %s got %s = %s + %s for add 100ths (banker's)");
471 check_binary_op (gnc_numeric_create(-5833, 10000),
475 a, b,
"expected %s got %s = %s + %s for add 4 sig figs");
477 check_binary_op (gnc_numeric_create(-583333, 1000000),
481 a, b,
"expected %s got %s = %s + %s for add 6 sig figs");
483 check_binary_op (gnc_numeric_create(-1, 12),
485 a, b,
"expected %s got %s = %s - %s for sub exact");
488 check_binary_op (gnc_numeric_create(-1, 12),
490 a, b,
"expected %s got %s = %s - %s for sub reduce");
492 check_binary_op (gnc_numeric_create(-1, 12),
494 a, b,
"expected %s got %s = %s - %s for sub reduce");
496 check_binary_op (gnc_numeric_create(-8, 100),
498 a, b,
"expected %s got %s = %s - %s for sub 100ths (banker's)");
503 printf(
"add 100ths/error : %s + %s = %s + (error) %s\n\n",
504 gnc_numeric_print(a), gnc_numeric_print(b),
505 gnc_numeric_print(c),
506 gnc_numeric_print(err));
509 printf(
"sub 100ths/error : %s - %s = %s + (error) %s\n\n",
510 gnc_numeric_print(a), gnc_numeric_print(b),
511 gnc_numeric_print(c),
512 gnc_numeric_print(err));
518 for (i = 0; i < NREPS; i++)
521 gint64 deno = rand() + 1;
522 gint64 na = get_random_gint64();
523 gint64 nb = get_random_gint64();
530 a = gnc_numeric_create(na, deno);
531 b = gnc_numeric_create(nb, deno);
535 e = gnc_numeric_create(ne, deno);
538 a, b,
"expected %s got %s = %s + %s for exact addition");
542 e = gnc_numeric_create(ne, deno);
545 a, b,
"expected %s got %s = %s - %s for exact subtraction");
549 static const gint64 pten[] = { 1, 10, 100, 1000, 10000, 100000, 1000000,
550 10000000, 100000000, 1000000000, 10000000000,
551 100000000000, 1000000000000, 10000000000000,
552 100000000000000, 10000000000000000,
553 100000000000000000, 1000000000000000000};
554 #define POWTEN_OVERFLOW -5
559 if (exp > 18 || exp < -18)
560 return POWTEN_OVERFLOW;
561 return exp < 0 ? -pten[-exp] : pten[exp];
565 check_add_subtract_overflow (
void)
569 for (i = 0; i < NREPS; i++)
573 int exp_a = rand () % 1000;
574 int exp_b = rand () % 1000;
575 gint64 bin_deno_a = (exp_a == 0 ? 1 : exp_a);
576 gint64 bin_deno_b = (exp_b == 0 ? 1 : exp_b);
583 gint64 dec_deno_a = powten (exp_a % 7);
584 gint64 dec_deno_b = powten (exp_b % 7);
585 gint64 na = get_random_gint64 () % (1000000 * dec_deno_a);
586 gint64 nb = get_random_gint64 () % (1000000 * dec_deno_b);
591 gnc_numeric ba = gnc_numeric_create(na, bin_deno_a);
592 gnc_numeric bb = gnc_numeric_create(nb, bin_deno_b);
593 gnc_numeric da = gnc_numeric_create(na, dec_deno_a);
594 gnc_numeric db = gnc_numeric_create(nb, dec_deno_b);
605 errmsg = g_strdup_printf (
"%s + %s raised %s", ba_str, bb_str,
607 do_test (err == 0, errmsg);
612 errmsg = g_strdup_printf (
"%s + %s raised %s", da_str, bb_str,
614 do_test (err == 0, errmsg);
618 errmsg = g_strdup_printf (
"%s + %s raised %s", ba_str, db_str,
620 do_test (err == 0, errmsg);
625 errmsg = g_strdup_printf (
"%s + %s raised %s", da_str, db_str,
627 do_test (err == 0, errmsg);
633 errmsg = g_strdup_printf (
"%s + %s raised %s", ba_str, bb_str,
635 do_test (err == 0, errmsg);
640 errmsg = g_strdup_printf (
"%s + %s raised %s", da_str, bb_str,
642 do_test (err == 0, errmsg);
646 errmsg = g_strdup_printf (
"%s + %s raised %s", ba_str, db_str,
648 do_test (err == 0, errmsg);
653 errmsg = g_strdup_printf (
"%s + %s raised %s", da_str, db_str,
655 do_test (err == 0, errmsg);
670 check_mult_div (
void)
678 a = gnc_numeric_create(-100, 100);
679 b = gnc_numeric_create(1, 1);
680 check_binary_op (gnc_numeric_create(-100, 100),
682 a, b,
"expected %s got %s = %s / %s div exact");
684 a = gnc_numeric_create(-100, 100);
685 b = gnc_numeric_create(-1, 1);
686 check_binary_op (gnc_numeric_create(100, 100),
688 a, b,
"expected %s got %s = %s / %s div exact");
690 a = gnc_numeric_create(-100, 100);
691 b = gnc_numeric_create(-1, 1);
692 check_binary_op (gnc_numeric_create(100, 100),
694 a, b,
"expected %s got %s = %s * %s mult exact");
696 a = gnc_numeric_create(2, 6);
697 b = gnc_numeric_create(1, 4);
699 check_binary_op (gnc_numeric_create(2, 24),
701 a, b,
"expected %s got %s = %s * %s for mult exact");
703 check_binary_op (gnc_numeric_create(1, 12),
705 a, b,
"expected %s got %s = %s * %s for mult reduce");
707 check_binary_op (gnc_numeric_create(8, 100),
709 a, b,
"expected %s got %s = %s * %s for mult 100th's");
711 check_binary_op (gnc_numeric_create(8, 6),
713 a, b,
"expected %s got %s = %s / %s for div exact");
715 check_binary_op (gnc_numeric_create(4, 3),
717 a, b,
"expected %s got %s = %s / %s for div reduce");
719 check_binary_op (gnc_numeric_create(133, 100),
721 a, b,
"expected %s got %s = %s * %s for div 100th's");
726 printf(
"mul 100ths/error : %s * %s = %s + (error) %s\n\n",
727 gnc_numeric_print(a), gnc_numeric_print(b),
728 gnc_numeric_print(c),
729 gnc_numeric_print(err));
732 printf(
"div 100ths/error : %s / %s = %s + (error) %s\n\n",
733 gnc_numeric_print(a), gnc_numeric_print(b),
734 gnc_numeric_print(c),
735 gnc_numeric_print(err));
743 a = gnc_numeric_create(1 * v, v);
744 b = gnc_numeric_create(10000000 * v, v);
748 a, b,
"expected %s got %s = %s * %s for multiply");
753 for (i = 0; i < NREPS; i++)
772 a = gnc_numeric_create(na, deno);
773 b = gnc_numeric_create(nb, deno);
775 check_binary_op_equal (gnc_numeric_create(ne, 1),
777 a, b,
"expected %s got %s = %s * %s for mult exact");
780 for (j = 1; j < 31; j++)
782 a = gnc_numeric_create(na << j, 1 << j);
783 b = gnc_numeric_create(nb << j, 1 << j);
784 check_binary_op (gnc_numeric_create(ne, 1),
786 a, b,
"expected %s got %s = %s * %s for mult reduce");
790 b = gnc_numeric_create(deno, nb);
792 check_binary_op_equal (gnc_numeric_create(ne, 1),
794 a, b,
"expected %s got %s = %s / %s for div exact");
800 for (j = 1; j < 16; j++)
802 a = gnc_numeric_create(na << j, 1 << j);
803 b = gnc_numeric_create(1 << j, nb << j);
804 check_binary_op (gnc_numeric_create(ne, 1),
806 a, b,
"expected %s got %s = %s / %s for div reduce");
810 a = gnc_numeric_create(782592055622866ULL, 89025);
811 b = gnc_numeric_create(2222554708930978ULL, 85568);
831 a, b,
"expected %s got %s = %s / %s for div exact");
833 check_binary_op (gnc_numeric_create(338441, 1000000),
836 a, b,
"expected %s got %s = %s / %s for div round");
846 a = gnc_numeric_create (-47497125586LL, 82718);
847 b = gnc_numeric_create (-69100955LL, 55739);
849 d = gnc_numeric_create (-32005637020LL, 55739);
851 check_binary_op (gnc_numeric_create(-102547458LL, 82718),
854 c, d,
"expected %s got %s = %s / %s for div round");
861 c, d,
"expected %s got %s = %s / %s for div round");
864 amt_a = gnc_numeric_create (-6005287905LL, 40595);
865 amt_tot = gnc_numeric_create (-8744187958LL, 40595);
869 check_binary_op (gnc_numeric_create(6005287905LL, 8744187958LL),
870 frac, amt_a, amt_tot,
871 "expected %s got %s = %s / %s for div reduce");
874 val_tot = gnc_numeric_create (-4280656418LL, 19873);
876 gnc_numeric_denom(val_tot),
878 check_binary_op (gnc_numeric_create(-2939846940LL, 19873),
879 val_a, val_tot, frac,
880 "expected %s got %s = %s * %s for mult round");
882 frac = gnc_numeric_create (396226789777979LL, 328758834367851752LL);
883 val_tot = gnc_numeric_create (467013515494988LL, 100);
885 gnc_numeric_denom(val_tot),
887 check_binary_op (gnc_numeric_create(562854124919LL, 100),
888 val_a, val_tot, frac,
889 "expected %s got %s = %s * %s for mult round");
892 a = gnc_numeric_create (40066447153986554LL, 4518);
893 b = gnc_numeric_create (26703286457229LL, 3192);
899 check_binary_op (gnc_numeric_create(106007, 100),
901 "expected %s got %s = %s / %s for mult sigfigs");
906 check_reciprocal(
void)
911 val = gnc_numeric_create(-60, 20);
915 val,
"expected %s got %s = (%s as RECIP(1))");
917 a = gnc_numeric_create(200, 100);
918 b = gnc_numeric_create(300, 100);
922 check_binary_op (gnc_numeric_create(5, -1),
923 ans, a, b,
"expected %s got %s = %s + %s for reciprocal");
926 a = gnc_numeric_create(2, -1);
927 b = gnc_numeric_create(300, 100);
929 check_binary_op (gnc_numeric_create(5, -1),
930 ans, a, b,
"expected %s got %s = %s + %s for reciprocal");
934 do_test ((5.0 == flo),
"reciprocal conversion");
937 a = gnc_numeric_create(2, 1);
938 b = gnc_numeric_create(2, -1);
940 a = gnc_numeric_create(2, 1);
941 b = gnc_numeric_create(3, -1);
943 a = gnc_numeric_create(-2, 1);
944 b = gnc_numeric_create(2, -1);
946 a = gnc_numeric_create(2, -1);
947 b = gnc_numeric_create(3, -1);
951 a = gnc_numeric_create(2, 1);
952 b = gnc_numeric_create(2, -1);
956 a = gnc_numeric_create(2, 1);
957 b = gnc_numeric_create(3, -1);
959 check_binary_op (gnc_numeric_create(6, -1),
960 ans, a, b,
"expected %s got %s = %s * %s for reciprocal");
964 a = gnc_numeric_create(-60, 1);
965 b = gnc_numeric_create(2, -10);
967 check_binary_op (gnc_numeric_create(-3, -1),
968 ans, a, b,
"expected %s got %s = %s / %s for reciprocal");
971 a = gnc_numeric_create(60, 1);
972 b = gnc_numeric_create(2, -10);
974 check_binary_op (gnc_numeric_create(3, -1),
975 ans, a, b,
"expected %s got %s = %s / %s for reciprocal");
985 check_eq_operator ();
987 check_equality_operator ();
991 check_add_subtract();
992 check_add_subtract_overflow ();
998 main (
int argc,
char **argv)
1001 if (cashobjects_register())
1004 print_test_results();
gnc_numeric gnc_numeric_mul_with_error(gnc_numeric a, gnc_numeric b, gint64 denom, gint how, gnc_numeric *error)
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
gnc_numeric double_to_gnc_numeric(double n, gint64 denom, gint how)
gnc_numeric gnc_numeric_add_with_error(gnc_numeric a, gnc_numeric b, gint64 denom, gint how, gnc_numeric *error)
gnc_numeric gnc_numeric_neg(gnc_numeric a)
An exact-rational-number library for gnucash. (to be renamed qofnumeric.h in libqof2) ...
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
gint gnc_numeric_compare(gnc_numeric a, gnc_numeric b)
gchar * gnc_numeric_to_string(gnc_numeric n)
gnc_numeric gnc_numeric_sub_with_error(gnc_numeric a, gnc_numeric b, gint64 denom, gint how, gnc_numeric *error)
gnc_numeric gnc_numeric_reduce(gnc_numeric n)
gdouble gnc_numeric_to_double(gnc_numeric n)
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
#define GNC_DENOM_RECIPROCAL(a)
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
const char * gnc_numeric_errorCode_to_string(GNCNumericErrorCode error_code)
gnc_numeric gnc_numeric_error(GNCNumericErrorCode error_code)
gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y, gint64 denom, gint how)
gboolean gnc_numeric_eq(gnc_numeric a, gnc_numeric b)
gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
void qof_close(void)
Safely close down the Query Object Framework.
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
void qof_init(void)
Initialise the Query Object Framework.
#define GNC_HOW_DENOM_SIGFIGS(n)
gnc_numeric gnc_numeric_div_with_error(gnc_numeric a, gnc_numeric b, gint64 denom, gint how, gnc_numeric *error)