00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <ctype.h>
00029 #include <glib.h>
00030 #include "qof.h"
00031 #include "test-stuff.h"
00032 #include "test-engine-stuff.h"
00033 #include "gnc-numeric.h"
00034
00035 #define NREPS 2000
00036
00037 static char *
00038 gnc_numeric_print(gnc_numeric in)
00039 {
00040 char * retval;
00041 if(gnc_numeric_check(in))
00042 {
00043 retval = g_strdup_printf("<ERROR> [%" G_GINT64_FORMAT " / %" G_GINT64_FORMAT "]",
00044 in.num,
00045 in.denom);
00046 }
00047 else
00048 {
00049 retval = g_strdup_printf("[%" G_GINT64_FORMAT " / %" G_GINT64_FORMAT "]",
00050 in.num,
00051 in.denom);
00052 }
00053 return retval;
00054 }
00055
00056
00057
00058 static void
00059 check_unary_op (gboolean (*eqtest) (gnc_numeric, gnc_numeric),
00060 gnc_numeric expected,
00061 gnc_numeric actual,
00062 gnc_numeric input,
00063 const char * errmsg)
00064 {
00065 char *e = gnc_numeric_print (expected);
00066 char *r = gnc_numeric_print (actual);
00067 char *a = gnc_numeric_print (input);
00068 char *str = g_strdup_printf (errmsg, e,r, a);
00069
00070 do_test (eqtest(expected, actual), str);
00071
00072 g_free (a);
00073 g_free (r);
00074 g_free (e);
00075 g_free (str);
00076 }
00077
00078
00079
00080 static void
00081 check_binary_op (gnc_numeric expected,
00082 gnc_numeric actual,
00083 gnc_numeric input_a,
00084 gnc_numeric input_b,
00085 const char * errmsg)
00086 {
00087 char *e = gnc_numeric_print (expected);
00088 char *r = gnc_numeric_print (actual);
00089 char *a = gnc_numeric_print (input_a);
00090 char *b = gnc_numeric_print (input_b);
00091 char *str = g_strdup_printf (errmsg, e,r,a,b);
00092
00093 do_test (gnc_numeric_eq(expected, actual), str);
00094
00095 g_free (a);
00096 g_free (b);
00097 g_free (r);
00098 g_free (e);
00099 g_free (str);
00100 }
00101
00102
00103
00104 static gboolean
00105 gnc_numeric_unequal (gnc_numeric a, gnc_numeric b)
00106 {
00107 return (0 == gnc_numeric_equal (a,b));
00108 }
00109
00110
00111
00112
00113
00114 static void
00115 check_eq_operator (void)
00116 {
00117 gnc_numeric a = gnc_numeric_create (42, 58);
00118 gnc_numeric b = gnc_numeric_create (42, 58);
00119 gnc_numeric c = gnc_numeric_create (40, 58);
00120
00121
00122 do_test (gnc_numeric_eq(a, a), "expected self-equivalence");
00123 do_test (gnc_numeric_eq(a, b), "expected equivalence");
00124 do_test (0 == gnc_numeric_eq(a, c), "expected inequivalence");
00125 }
00126
00127
00128
00129 static void
00130 check_reduce (void)
00131 {
00132 gnc_numeric one, rone;
00133 gnc_numeric four, rfour;
00134 gnc_numeric val, rval;
00135
00136 one = gnc_numeric_create (1,1);
00137 rone = gnc_numeric_create (1000000,1000000);
00138 rone = gnc_numeric_reduce (rone);
00139 do_test (gnc_numeric_eq(one, rone), "reduce to one");
00140
00141 four = gnc_numeric_create (4,1);
00142 rfour = gnc_numeric_create (480,120);
00143 rfour = gnc_numeric_reduce (rfour);
00144 do_test (gnc_numeric_eq(four, rfour), "reduce to four");
00145
00146 val = gnc_numeric_create(10023234LL, 334216654LL);
00147 rval = gnc_numeric_reduce (val);
00148 check_unary_op (gnc_numeric_eq,
00149 gnc_numeric_create (5011617,167108327),
00150 rval,
00151 val, "check_reduce(1) expected %s = %s = reduce(%s)");
00152
00153 val = gnc_numeric_create(17474724864LL,136048896LL);
00154 rval = gnc_numeric_reduce (val);
00155 check_unary_op (gnc_numeric_eq,
00156 gnc_numeric_create (4*17*17,9),
00157 rval,
00158 val, "check_reduce(2) expected %s = %s = reduce(%s)");
00159
00160 val = gnc_numeric_create(1024LL,1099511627776LL);
00161 rval = gnc_numeric_reduce (val);
00162 check_unary_op (gnc_numeric_eq,
00163 gnc_numeric_create (1,1024*1024*1024),
00164 rval,
00165 val, "check_reduce(3): expected %s = %s = reduce(%s)");
00166 }
00167
00168
00169
00170 static void
00171 check_equality_operator (void)
00172 {
00173 int i, m;
00174 gint mult;
00175 gint64 f, deno, numer;
00176 gnc_numeric big, rbig;
00177 gnc_numeric val, mval;
00178 gnc_numeric bval, rval;
00179
00180 numer = 1<<30;
00181 numer <<= 30;
00182 deno = 1<<30;
00183 deno <<= 20;
00184 rbig = gnc_numeric_create (numer, deno);
00185
00186 big = gnc_numeric_create (1<<10,1);
00187 do_test (gnc_numeric_equal(big, rbig), "equal to billion");
00188
00189 big = gnc_numeric_create (1<<20,1<<10);
00190 do_test (gnc_numeric_equal(big, rbig), "equal to 1<<20/1<<10");
00191
00192 big = gnc_numeric_create (1<<30,1<<20);
00193 do_test (gnc_numeric_equal(big, rbig), "equal to 1<<30/1<<20");
00194
00195 numer = 1<<30;
00196 numer <<= 30;
00197 deno = 1<<30;
00198 rbig = gnc_numeric_create (numer, deno);
00199
00200 big = gnc_numeric_create (1<<30,1);
00201 do_test (gnc_numeric_equal(big, rbig), "equal to 1<<30");
00202
00203 numer = 1<<30;
00204 numer <<= 10;
00205 big = gnc_numeric_create (numer, 1<<10);
00206 do_test (gnc_numeric_equal(big, rbig), "equal to 1<<40/1<<10");
00207
00208 numer <<= 10;
00209 big = gnc_numeric_create (numer, 1<<20);
00210 do_test (gnc_numeric_equal(big, rbig), "equal to 1<<50/1<<20");
00211
00212
00213 for (i=0; i<NREPS; i++)
00214 {
00215 deno = rand() / 2;
00216 mult = rand() / 2;
00217 numer = rand() / 2;
00218
00219 val = gnc_numeric_create (numer, deno);
00220 mval = gnc_numeric_create (numer*mult, deno*mult);
00221
00222
00223 bval = gnc_numeric_reduce (val);
00224 rval = gnc_numeric_reduce (mval);
00225 check_unary_op (gnc_numeric_eq,
00226 bval, rval, mval, "expected %s = %s = reduce(%s)");
00227
00228
00229 check_unary_op (gnc_numeric_equal,
00230 val, mval, mval, "expected %s = %s");
00231
00232
00233
00234
00235 mval.denom >>= 1;
00236 mval.num >>= 1;
00237 m=0;
00238 f = mval.denom;
00239 while (f%2 == 0)
00240 {
00241 f >>= 1;
00242 m++;
00243 }
00244 if (1 < m)
00245 {
00246 gint64 nn = 1 << (32-m);
00247 nn <<= 32;
00248 nn += mval.num;
00249 val = gnc_numeric_create (2*nn, 2*mval.denom);
00250 check_unary_op (gnc_numeric_unequal,
00251 val, mval, mval, "expected unequality %s != %s");
00252
00253 }
00254 }
00255 }
00256
00257
00258
00259 static void
00260 check_rounding (void)
00261 {
00262 gnc_numeric val;
00263
00264 val = gnc_numeric_create(7, 16);
00265 check_unary_op (gnc_numeric_eq,
00266 gnc_numeric_create (43,100),
00267 gnc_numeric_convert (val, 100, GNC_HOW_RND_FLOOR),
00268 val, "expected %s = %s = (%s as 100th's floor)");
00269 check_unary_op (gnc_numeric_eq,
00270 gnc_numeric_create (44,100),
00271 gnc_numeric_convert (val, 100, GNC_HOW_RND_CEIL),
00272 val, "expected %s = %s = (%s as 100th's ceiling)");
00273 check_unary_op (gnc_numeric_eq,
00274 gnc_numeric_create (43,100),
00275 gnc_numeric_convert (val, 100, GNC_HOW_RND_TRUNC),
00276 val, "expected %s = %s = (%s as 100th's trunc)");
00277 check_unary_op (gnc_numeric_eq,
00278 gnc_numeric_create (44,100),
00279 gnc_numeric_convert (val, 100, GNC_HOW_RND_ROUND),
00280 val, "expected %s = %s = (%s as 100th's round)");
00281
00282 val = gnc_numeric_create(1511, 1000);
00283 check_unary_op (gnc_numeric_eq,
00284 gnc_numeric_create (151,100),
00285 gnc_numeric_convert (val, 100, GNC_HOW_RND_ROUND),
00286 val, "expected %s = %s = (%s as 100th's round)");
00287
00288 val = gnc_numeric_create(1516, 1000);
00289 check_unary_op (gnc_numeric_eq,
00290 gnc_numeric_create (152,100),
00291 gnc_numeric_convert (val, 100, GNC_HOW_RND_ROUND),
00292 val, "expected %s = %s = (%s as 100th's round)");
00293
00294
00295 val = gnc_numeric_create(1515, 1000);
00296 check_unary_op (gnc_numeric_eq,
00297 gnc_numeric_create (152,100),
00298 gnc_numeric_convert (val, 100, GNC_HOW_RND_ROUND),
00299 val, "expected %s = %s = (%s as 100th's round)");
00300
00301 val = gnc_numeric_create(1525, 1000);
00302 check_unary_op (gnc_numeric_eq,
00303 gnc_numeric_create (152,100),
00304 gnc_numeric_convert (val, 100, GNC_HOW_RND_ROUND),
00305 val, "expected %s = %s = (%s as 100th's round)");
00306
00307 val = gnc_numeric_create(1535, 1000);
00308 check_unary_op (gnc_numeric_eq,
00309 gnc_numeric_create (154,100),
00310 gnc_numeric_convert (val, 100, GNC_HOW_RND_ROUND),
00311 val, "expected %s = %s = (%s as 100th's round)");
00312
00313 val = gnc_numeric_create(1545, 1000);
00314 check_unary_op (gnc_numeric_eq,
00315 gnc_numeric_create (154,100),
00316 gnc_numeric_convert (val, 100, GNC_HOW_RND_ROUND),
00317 val, "expected %s = %s = (%s as 100th's round)");
00318 }
00319
00320
00321
00322 static void
00323 check_double (void)
00324 {
00325 double flo;
00326 gnc_numeric val = gnc_numeric_create (0,1);
00327
00328 check_unary_op (gnc_numeric_eq,
00329 gnc_numeric_create (112346,100000),
00330 double_to_gnc_numeric(1.1234567890123,
00331 GNC_DENOM_AUTO,
00332 GNC_HOW_DENOM_SIGFIGS(6) |
00333 GNC_HOW_RND_ROUND),
00334 val, "expected %s = %s double 6 figs");
00335
00336 check_unary_op (gnc_numeric_eq,
00337 gnc_numeric_create (112346,10000000),
00338 double_to_gnc_numeric(0.011234567890123,
00339 GNC_DENOM_AUTO,
00340 GNC_HOW_DENOM_SIGFIGS(6) |
00341 GNC_HOW_RND_ROUND),
00342 val, "expected %s = %s double 6 figs");
00343
00344 check_unary_op (gnc_numeric_eq,
00345 gnc_numeric_create (112346,100),
00346 double_to_gnc_numeric(1123.4567890123,
00347 GNC_DENOM_AUTO,
00348 GNC_HOW_DENOM_SIGFIGS(6) |
00349 GNC_HOW_RND_ROUND),
00350 val, "expected %s = %s double 6 figs");
00351 check_unary_op (gnc_numeric_eq,
00352 gnc_numeric_create (112346,10000000000LL),
00353 double_to_gnc_numeric(1.1234567890123e-5,
00354 GNC_DENOM_AUTO,
00355 GNC_HOW_DENOM_SIGFIGS(6) |
00356 GNC_HOW_RND_ROUND),
00357 val, "expected %s = %s double 6 figs");
00358
00359 flo = gnc_numeric_to_double(gnc_numeric_create(7, 16));
00360 do_test ((0.4375 == flo), "float pt conversion");
00361 }
00362
00363
00364
00365 static void
00366 check_neg (void)
00367 {
00368 gnc_numeric a = gnc_numeric_create(2, 6);
00369 gnc_numeric b = gnc_numeric_create(1, 4);
00370 gnc_numeric c = gnc_numeric_neg (a);
00371 gnc_numeric d = gnc_numeric_neg (b);
00372
00373 check_unary_op (gnc_numeric_eq,
00374 gnc_numeric_create (-2,6), c,
00375 a, "expected %s = %s = -(%s)");
00376
00377 check_unary_op (gnc_numeric_eq,
00378 gnc_numeric_create (-1,4), d,
00379 b, "expected %s = %s = -(%s)");
00380
00381 }
00382
00383
00384
00385 static void
00386 check_add_subtract (void)
00387 {
00388 int i;
00389 gnc_numeric a, b, c, d, z;
00390 #if CHECK_ERRORS_TOO
00391 gnc_numeric c;
00392 #endif
00393
00394 a = gnc_numeric_create(2, 6);
00395 b = gnc_numeric_create(1, 4);
00396
00397
00398 check_binary_op (gnc_numeric_create(7,12),
00399 gnc_numeric_add(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT),
00400 a, b, "expected %s got %s = %s + %s for add exact");
00401
00402 check_binary_op (gnc_numeric_create(58,100),
00403 gnc_numeric_add(a, b, 100, GNC_HOW_RND_ROUND),
00404 a, b, "expected %s got %s = %s + %s for add 100ths (banker's)");
00405
00406 check_binary_op (gnc_numeric_create(5833,10000),
00407 gnc_numeric_add(a, b, GNC_DENOM_AUTO,
00408 GNC_HOW_DENOM_SIGFIGS(4) |
00409 GNC_HOW_RND_ROUND),
00410 a, b, "expected %s got %s = %s + %s for add 4 sig figs");
00411
00412 check_binary_op (gnc_numeric_create(583333,1000000),
00413 gnc_numeric_add(a, b, GNC_DENOM_AUTO,
00414 GNC_HOW_DENOM_SIGFIGS(6) |
00415 GNC_HOW_RND_ROUND),
00416 a, b, "expected %s got %s = %s + %s for add 6 sig figs");
00417
00418 check_binary_op (gnc_numeric_create(1,12),
00419 gnc_numeric_sub(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT),
00420 a, b, "expected %s got %s = %s - %s for sub exact");
00421
00422
00423 check_binary_op (gnc_numeric_create(1,12),
00424 gnc_numeric_sub(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE),
00425 a, b, "expected %s got %s = %s - %s for sub reduce");
00426
00427 check_binary_op (gnc_numeric_create(1,12),
00428 gnc_numeric_sub(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD),
00429 a, b, "expected %s got %s = %s - %s for sub reduce");
00430
00431 check_binary_op (gnc_numeric_create(8,100),
00432 gnc_numeric_sub(a, b, 100, GNC_HOW_RND_ROUND),
00433 a, b, "expected %s got %s = %s - %s for sub 100ths (banker's)");
00434
00435
00436
00437 c = gnc_numeric_neg (a);
00438 d = gnc_numeric_neg (b);
00439 z = gnc_numeric_zero();
00440 check_binary_op (c, gnc_numeric_add_fixed(z,c),
00441 z, c, "expected %s got %s = %s + %s for add fixed");
00442
00443 check_binary_op (d, gnc_numeric_add_fixed(z,d),
00444 z, d, "expected %s got %s = %s + %s for add fixed");
00445
00446
00447
00448 a = c;
00449 b = d;
00450
00451 check_binary_op (gnc_numeric_create(-7,12),
00452 gnc_numeric_add(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT),
00453 a, b, "expected %s got %s = %s + %s for add exact");
00454
00455 check_binary_op (gnc_numeric_create(-58,100),
00456 gnc_numeric_add(a, b, 100, GNC_HOW_RND_ROUND),
00457 a, b, "expected %s got %s = %s + %s for add 100ths (banker's)");
00458
00459 check_binary_op (gnc_numeric_create(-5833,10000),
00460 gnc_numeric_add(a, b, GNC_DENOM_AUTO,
00461 GNC_HOW_DENOM_SIGFIGS(4) |
00462 GNC_HOW_RND_ROUND),
00463 a, b, "expected %s got %s = %s + %s for add 4 sig figs");
00464
00465 check_binary_op (gnc_numeric_create(-583333,1000000),
00466 gnc_numeric_add(a, b, GNC_DENOM_AUTO,
00467 GNC_HOW_DENOM_SIGFIGS(6) |
00468 GNC_HOW_RND_ROUND),
00469 a, b, "expected %s got %s = %s + %s for add 6 sig figs");
00470
00471 check_binary_op (gnc_numeric_create(-1,12),
00472 gnc_numeric_sub(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT),
00473 a, b, "expected %s got %s = %s - %s for sub exact");
00474
00475
00476 check_binary_op (gnc_numeric_create(-1,12),
00477 gnc_numeric_sub(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE),
00478 a, b, "expected %s got %s = %s - %s for sub reduce");
00479
00480 check_binary_op (gnc_numeric_create(-1,12),
00481 gnc_numeric_sub(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD),
00482 a, b, "expected %s got %s = %s - %s for sub reduce");
00483
00484 check_binary_op (gnc_numeric_create(-8,100),
00485 gnc_numeric_sub(a, b, 100, GNC_HOW_RND_ROUND),
00486 a, b, "expected %s got %s = %s - %s for sub 100ths (banker's)");
00487
00488
00489 #if CHECK_ERRORS_TOO
00490 c = gnc_numeric_add_with_error(a, b, 100, GNC_HOW_RND_ROUND, &err);
00491 printf("add 100ths/error : %s + %s = %s + (error) %s\n\n",
00492 gnc_numeric_print(a), gnc_numeric_print(b),
00493 gnc_numeric_print(c),
00494 gnc_numeric_print(err));
00495
00496 c = gnc_numeric_sub_with_error(a, b, 100, GNC_HOW_RND_FLOOR, &err);
00497 printf("sub 100ths/error : %s - %s = %s + (error) %s\n\n",
00498 gnc_numeric_print(a), gnc_numeric_print(b),
00499 gnc_numeric_print(c),
00500 gnc_numeric_print(err));
00501
00502 #endif
00503
00504
00505
00506 for (i=0; i<NREPS; i++)
00507 {
00508 gnc_numeric e;
00509 gint64 deno = rand() +1;
00510 gint64 na = get_random_gint64();
00511 gint64 nb = get_random_gint64();
00512 gint64 ne;
00513
00514
00515 na /=2;
00516 nb /=2;
00517
00518 a = gnc_numeric_create(na, deno);
00519 b = gnc_numeric_create(nb, deno);
00520
00521
00522 ne = na+nb;
00523 e = gnc_numeric_create(ne, deno);
00524 check_binary_op (e,
00525 gnc_numeric_add(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT),
00526 a, b, "expected %s got %s = %s + %s for exact addition");
00527
00528
00529 ne = na-nb;
00530 e = gnc_numeric_create(ne, deno);
00531 check_binary_op (e,
00532 gnc_numeric_sub(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT),
00533 a, b, "expected %s got %s = %s - %s for exact subtraction");
00534 }
00535 }
00536
00537
00538
00539 static void
00540 check_mult_div (void)
00541 {
00542 int i, j;
00543 gint64 v;
00544 gnc_numeric c, d;
00545 gnc_numeric amt_a, amt_tot, frac, val_tot, val_a;
00546 gnc_numeric a, b;
00547
00548 a = gnc_numeric_create(-100, 100);
00549 b = gnc_numeric_create(1, 1);
00550 check_binary_op (gnc_numeric_create(-100, 100),
00551 gnc_numeric_div(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT),
00552 a, b, "expected %s got %s = %s / %s div exact");
00553
00554 a = gnc_numeric_create(-100, 100);
00555 b = gnc_numeric_create(-1, 1);
00556 check_binary_op (gnc_numeric_create(100, 100),
00557 gnc_numeric_div(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT),
00558 a, b, "expected %s got %s = %s / %s div exact");
00559
00560 a = gnc_numeric_create(-100, 100);
00561 b = gnc_numeric_create(-1, 1);
00562 check_binary_op (gnc_numeric_create(100, 100),
00563 gnc_numeric_mul(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT),
00564 a, b, "expected %s got %s = %s * %s mult exact");
00565
00566 a = gnc_numeric_create(2, 6);
00567 b = gnc_numeric_create(1, 4);
00568
00569 check_binary_op (gnc_numeric_create(2,24),
00570 gnc_numeric_mul(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT),
00571 a, b, "expected %s got %s = %s * %s for mult exact");
00572
00573 check_binary_op (gnc_numeric_create(1,12),
00574 gnc_numeric_mul(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE),
00575 a, b, "expected %s got %s = %s * %s for mult reduce");
00576
00577 check_binary_op (gnc_numeric_create(8,100),
00578 gnc_numeric_mul(a, b, 100, GNC_HOW_RND_ROUND),
00579 a, b, "expected %s got %s = %s * %s for mult 100th's");
00580
00581 check_binary_op (gnc_numeric_create(8,6),
00582 gnc_numeric_div(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT),
00583 a, b, "expected %s got %s = %s / %s for div exact");
00584
00585 check_binary_op (gnc_numeric_create(4,3),
00586 gnc_numeric_div(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE),
00587 a, b, "expected %s got %s = %s / %s for div reduce");
00588
00589 check_binary_op (gnc_numeric_create(133,100),
00590 gnc_numeric_div(a, b, 100, GNC_HOW_RND_ROUND),
00591 a, b, "expected %s got %s = %s * %s for div 100th's");
00592
00593 #if CHECK_ERRORS_TOO
00594 gnc_numeric c;
00595 c = gnc_numeric_mul_with_error(a, b, 100, GNC_HOW_RND_ROUND, &err);
00596 printf("mul 100ths/error : %s * %s = %s + (error) %s\n\n",
00597 gnc_numeric_print(a), gnc_numeric_print(b),
00598 gnc_numeric_print(c),
00599 gnc_numeric_print(err));
00600
00601 c = gnc_numeric_div_with_error(a, b, 100, GNC_HOW_RND_ROUND, &err);
00602 printf("div 100ths/error : %s / %s = %s + (error) %s\n\n",
00603 gnc_numeric_print(a), gnc_numeric_print(b),
00604 gnc_numeric_print(c),
00605 gnc_numeric_print(err));
00606
00607 #endif
00608
00609
00610
00611
00612 v = 1000000;
00613 a = gnc_numeric_create(1*v, v);
00614 b = gnc_numeric_create(10000000*v, v);
00615
00616 check_binary_op (b,
00617 gnc_numeric_mul(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD),
00618 a, b, "expected %s got %s = %s * %s for multiply");
00619
00620
00621
00622
00623 for (i=0; i<NREPS; i++)
00624 {
00625 gint64 deno = 1;
00626 gint64 na = rand();
00627 gint64 nb = rand();
00628 gint64 ne;
00629
00630
00631 na /= 2;
00632 nb /= 2;
00633 ne = na*nb;
00634
00635 a = gnc_numeric_create(na, deno);
00636 b = gnc_numeric_create(nb, deno);
00637
00638 check_binary_op (gnc_numeric_create(ne,1),
00639 gnc_numeric_mul(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT),
00640 a, b, "expected %s got %s = %s * %s for mult exact");
00641
00642
00643 for (j=1; j<31; j++)
00644 {
00645 a = gnc_numeric_create(na << j, 1<<j);
00646 b = gnc_numeric_create(nb << j, 1<<j);
00647 check_binary_op (gnc_numeric_create(ne, 1),
00648 gnc_numeric_mul(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE),
00649 a, b, "expected %s got %s = %s * %s for mult reduce");
00650 }
00651
00652
00653 b = gnc_numeric_create(deno, nb);
00654
00655 check_binary_op (gnc_numeric_create(ne,1),
00656 gnc_numeric_div(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT),
00657 a, b, "expected %s got %s = %s / %s for div exact");
00658
00659
00660 na /= 2;
00661 nb /= 2;
00662 ne = na*nb;
00663 for (j=1; j<16; j++)
00664 {
00665 a = gnc_numeric_create(na << j, 1<<j);
00666 b = gnc_numeric_create(1<<j, nb << j);
00667 check_binary_op (gnc_numeric_create(ne, 1),
00668 gnc_numeric_div(a, b, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE),
00669 a, b, "expected %s got %s = %s / %s for div reduce");
00670 }
00671 }
00672
00673 a = gnc_numeric_create(782592055622866ULL,89025);
00674 b = gnc_numeric_create(2222554708930978ULL,85568);
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691 check_binary_op (gnc_numeric_error (GNC_ERROR_OVERFLOW),
00692 gnc_numeric_div(a, b, GNC_DENOM_AUTO,
00693 GNC_HOW_RND_NEVER | GNC_HOW_DENOM_EXACT),
00694 a, b, "expected %s got %s = %s / %s for div exact");
00695
00696 check_binary_op (gnc_numeric_create(338441, 1000000),
00697 gnc_numeric_div(a, b, GNC_DENOM_AUTO,
00698 GNC_HOW_DENOM_SIGFIGS(6) | GNC_HOW_RND_ROUND),
00699 a, b, "expected %s got %s = %s / %s for div round");
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709 a = gnc_numeric_create (-47497125586LL, 82718);
00710 b = gnc_numeric_create (-69100955LL, 55739);
00711 c = gnc_numeric_mul (a,b, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT);
00712 d = gnc_numeric_create (-32005637020LL, 55739);
00713
00714 check_binary_op (gnc_numeric_create(-102547458LL, 82718),
00715 gnc_numeric_div(c, d, 82718,
00716 GNC_HOW_DENOM_EXACT),
00717 c, d, "expected %s got %s = %s / %s for div round");
00718
00719
00720
00721 check_binary_op (gnc_numeric_error (GNC_ERROR_REMAINDER),
00722 gnc_numeric_div(c, d, 82718,
00723 GNC_HOW_DENOM_EXACT|GNC_HOW_RND_NEVER),
00724 c, d, "expected %s got %s = %s / %s for div round");
00725
00726
00727 amt_a = gnc_numeric_create (-6005287905LL, 40595);
00728 amt_tot = gnc_numeric_create (-8744187958LL, 40595);
00729 frac = gnc_numeric_div (amt_a, amt_tot,
00730 GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
00731
00732 check_binary_op (gnc_numeric_create(6005287905LL, 8744187958LL),
00733 frac, amt_a, amt_tot,
00734 "expected %s got %s = %s / %s for div reduce");
00735
00736
00737 val_tot = gnc_numeric_create (-4280656418LL, 19873);
00738 val_a = gnc_numeric_mul (frac, val_tot,
00739 gnc_numeric_denom(val_tot),
00740 GNC_HOW_RND_ROUND| GNC_HOW_DENOM_EXACT);
00741 check_binary_op (gnc_numeric_create(-2939846940LL, 19873),
00742 val_a, val_tot, frac,
00743 "expected %s got %s = %s * %s for mult round");
00744
00745 frac = gnc_numeric_create (396226789777979LL, 328758834367851752LL);
00746 val_tot = gnc_numeric_create (467013515494988LL, 100);
00747 val_a = gnc_numeric_mul (frac, val_tot,
00748 gnc_numeric_denom(val_tot),
00749 GNC_HOW_RND_ROUND| GNC_HOW_DENOM_EXACT);
00750 check_binary_op (gnc_numeric_create(562854125307LL, 100),
00751 val_a, val_tot, frac,
00752 "expected %s got %s = %s * %s for mult round");
00753
00754
00755 a = gnc_numeric_create (40066447153986554LL, 4518);
00756 b = gnc_numeric_create (26703286457229LL, 3192);
00757 frac = gnc_numeric_div(a, b,
00758 GNC_DENOM_AUTO,
00759 GNC_HOW_DENOM_SIGFIGS(6) |
00760 GNC_HOW_RND_ROUND);
00761
00762 check_binary_op (gnc_numeric_create(106007, 100),
00763 frac, a, b,
00764 "expected %s got %s = %s / %s for mult sigfigs");
00765
00766 }
00767
00768 static void
00769 check_reciprocal(void)
00770 {
00771 gnc_numeric a, b, ans, val;
00772 double flo;
00773
00774 val = gnc_numeric_create(-60,20);
00775 check_unary_op (gnc_numeric_eq, gnc_numeric_create (-3, -1),
00776 gnc_numeric_convert(val, GNC_DENOM_RECIPROCAL(1),
00777 GNC_HOW_RND_NEVER),
00778 val, "expected %s = %s = (%s as RECIP(1))");
00779
00780 a = gnc_numeric_create(200, 100);
00781 b = gnc_numeric_create(300, 100);
00782
00783
00784 ans = gnc_numeric_add(a, b, GNC_DENOM_RECIPROCAL(1), GNC_HOW_RND_NEVER);
00785 check_binary_op (gnc_numeric_create(5, -1),
00786 ans, a, b, "expected %s got %s = %s + %s for reciprocal");
00787
00788
00789 a = gnc_numeric_create(2, -1);
00790 b = gnc_numeric_create(300, 100);
00791 ans = gnc_numeric_add(a, b, GNC_DENOM_RECIPROCAL(1), GNC_HOW_RND_NEVER);
00792 check_binary_op (gnc_numeric_create(5, -1),
00793 ans, a, b, "expected %s got %s = %s + %s for reciprocal");
00794
00795
00796
00797 a = gnc_numeric_create(2, -1);
00798 b = gnc_numeric_create(300, 100);
00799 ans = gnc_numeric_add(a, b, GNC_DENOM_RECIPROCAL(1), GNC_HOW_RND_NEVER);
00800 check_binary_op (gnc_numeric_create(5, -1),
00801 ans, a, b, "expected %s got %s = %s + %s for recirocal");
00802
00803
00804 flo = gnc_numeric_to_double(gnc_numeric_create(5, -1));
00805 do_test ((5.0 == flo), "reciprocal conversion");
00806
00807
00808 a = gnc_numeric_create(2, 1);
00809 b = gnc_numeric_create(2, -1);
00810 do_test((0 == gnc_numeric_compare(a, b)), " 2 == 2 ");
00811 a = gnc_numeric_create(2, 1);
00812 b = gnc_numeric_create(3, -1);
00813 do_test((-1 == gnc_numeric_compare(a, b)), " 2 < 3 ");
00814 a = gnc_numeric_create(-2, 1);
00815 b = gnc_numeric_create(2, -1);
00816 do_test((-1 == gnc_numeric_compare(a, b)), " -2 < 2 ");
00817 a = gnc_numeric_create(2, -1);
00818 b = gnc_numeric_create(3, -1);
00819 do_test((-1 == gnc_numeric_compare(a, b)), " 2 < 3 ");
00820
00821
00822 a = gnc_numeric_create(2, 1);
00823 b = gnc_numeric_create(2, -1);
00824 do_test(gnc_numeric_equal(a, b), " 2 == 2 ");
00825
00826
00827 a = gnc_numeric_create(2, 1);
00828 b = gnc_numeric_create(3, -1);
00829 ans = gnc_numeric_mul(a, b, GNC_DENOM_RECIPROCAL(1), GNC_HOW_RND_NEVER);
00830 check_binary_op (gnc_numeric_create(6, -1),
00831 ans, a, b, "expected %s got %s = %s * %s for recirocal");
00832
00833
00834
00835 a = gnc_numeric_create(-60, 1);
00836 b = gnc_numeric_create(2, -10);
00837 ans = gnc_numeric_div(a, b, GNC_DENOM_RECIPROCAL(1), GNC_HOW_RND_NEVER);
00838 check_binary_op (gnc_numeric_create(-3, -1),
00839 ans, a, b, "expected %s got %s = %s / %s for recirocal");
00840
00841
00842 a = gnc_numeric_create(60, 1);
00843 b = gnc_numeric_create(2, -10);
00844 ans = gnc_numeric_div(a, b, GNC_DENOM_RECIPROCAL(1), GNC_HOW_RND_NEVER);
00845 check_binary_op (gnc_numeric_create(3, -1),
00846 ans, a, b, "expected %s got %s = %s / %s for recirocal");
00847
00848
00849 }
00850
00851
00852
00853
00854 static void
00855 run_test (void)
00856 {
00857 check_eq_operator ();
00858 check_reduce ();
00859 check_equality_operator ();
00860 check_rounding();
00861 check_double();
00862 check_neg();
00863 check_add_subtract();
00864 check_mult_div ();
00865 check_reciprocal();
00866 }
00867
00868 int
00869 main (int argc, char **argv)
00870 {
00871 qof_init();
00872 run_test ();
00873
00874 print_test_results();
00875 exit(get_rv());
00876 qof_close();
00877 return 0;
00878 }
00879
00880