[BACK]Return to t-cmp_d.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / tests / mpz

Annotation of OpenXM_contrib/gmp/tests/mpz/t-cmp_d.c, Revision 1.1.1.1

1.1       ohara       1: /* Test mpz_cmp_d and mpz_cmpabs_d.
                      2:
                      3: Copyright 2001, 2002 Free Software Foundation, Inc.
                      4:
                      5: This file is part of the GNU MP Library.
                      6:
                      7: The GNU MP Library is free software; you can redistribute it and/or modify
                      8: it under the terms of the GNU Lesser General Public License as published by
                      9: the Free Software Foundation; either version 2.1 of the License, or (at your
                     10: option) any later version.
                     11:
                     12: The GNU MP Library is distributed in the hope that it will be useful, but
                     13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
                     15: License for more details.
                     16:
                     17: You should have received a copy of the GNU Lesser General Public License
                     18: along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
                     19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
                     20: MA 02111-1307, USA. */
                     21:
                     22: #include <stdio.h>
                     23: #include <stdlib.h>
                     24: #include <string.h>
                     25:
                     26: #include "gmp.h"
                     27: #include "gmp-impl.h"
                     28: #include "tests.h"
                     29:
                     30:
                     31: /* FIXME: Not sure if the tests here are exhaustive.  Ought to try to get
                     32:    each possible exit from mpz_cmp_d (and mpz_cmpabs_d) exercised.  */
                     33:
                     34:
                     35: #define SGN(n)  ((n) > 0 ? 1 : (n) < 0 ? -1 : 0)
                     36:
                     37:
                     38: void
                     39: check_one (const char *name, mpz_srcptr x, double y, int cmp, int cmpabs)
                     40: {
                     41:   int   got;
                     42:
                     43:   got = mpz_cmp_d (x, y);
                     44:   if (SGN(got) != cmp)
                     45:     {
                     46:       int i;
                     47:       printf    ("mpz_cmp_d wrong (from %s)\n", name);
                     48:       printf    ("  got  %d\n", got);
                     49:       printf    ("  want %d\n", cmp);
                     50:     fail:
                     51:       mpz_trace ("  x", x);
                     52:       printf    ("  y %g\n", y);
                     53:       mp_trace_base=-16;
                     54:       mpz_trace ("  x", x);
                     55:       printf    ("  y %A\n", y);
                     56:       printf    ("  y");
                     57:       for (i = 0; i < sizeof(y); i++)
                     58:         printf (" %02X", (unsigned) ((unsigned char *) &y)[i]);
                     59:       printf ("\n");
                     60:       abort ();
                     61:     }
                     62:
                     63:   got = mpz_cmpabs_d (x, y);
                     64:   if (SGN(got) != cmpabs)
                     65:     {
                     66:       printf    ("mpz_cmpabs_d wrong\n");
                     67:       printf    ("  got  %d\n", got);
                     68:       printf    ("  want %d\n", cmpabs);
                     69:       goto fail;
                     70:     }
                     71: }
                     72:
                     73:
                     74: void
                     75: check_data (void)
                     76: {
                     77:   static const struct {
                     78:     const char  *x;
                     79:     double      y;
                     80:     int         cmp, cmpabs;
                     81:
                     82:   } data[] = {
                     83:
                     84:     {  "0",  0.0,  0,  0 },
                     85:
                     86:     {  "1",  0.0,  1,  1 },
                     87:     { "-1",  0.0, -1,  1 },
                     88:
                     89:     {  "0",  1.0, -1, -1 },
                     90:     {  "0", -1.0,  1, -1 },
                     91:
                     92:     {  "0x1000000000000000000000000000000000000000000000000", 0.0,  1, 1 },
                     93:     { "-0x1000000000000000000000000000000000000000000000000", 0.0, -1, 1 },
                     94:
                     95:     {  "0",  1e100, -1, -1 },
                     96:     {  "0", -1e100,  1, -1 },
                     97:
                     98:     {  "2",  1.5,   1,  1 },
                     99:     {  "2", -1.5,   1,  1 },
                    100:     { "-2",  1.5,  -1,  1 },
                    101:     { "-2", -1.5,  -1,  1 },
                    102:   };
                    103:
                    104:   mpz_t  x;
                    105:   int    i;
                    106:
                    107:   mpz_init (x);
                    108:
                    109:   for (i = 0; i < numberof (data); i++)
                    110:     {
                    111:       mpz_set_str_or_abort (x, data[i].x, 0);
                    112:       check_one ("check_data", x, data[i].y, data[i].cmp, data[i].cmpabs);
                    113:     }
                    114:
                    115:   mpz_clear (x);
                    116: }
                    117:
                    118:
                    119: /* Equality of integers with up to 53 bits */
                    120: void
                    121: check_onebits (void)
                    122: {
                    123:   mpz_t   x, x2;
                    124:   double  y;
                    125:   int     i;
                    126:
                    127:   mpz_init_set_ui (x, 0L);
                    128:   mpz_init (x2);
                    129:
                    130:   for (i = 0; i < 512; i++)
                    131:     {
                    132:       mpz_mul_2exp (x, x, 1);
                    133:       mpz_add_ui (x, x, 1L);
                    134:
                    135:       y = mpz_get_d (x);
                    136:       mpz_set_d (x2, y);
                    137:
                    138:       /* stop if any truncation is occurring */
                    139:       if (mpz_cmp (x, x2) != 0)
                    140:         break;
                    141:
                    142:       check_one ("check_onebits", x, y, 0, 0);
                    143:       check_one ("check_onebits", x, -y, 1, 0);
                    144:       mpz_neg (x, x);
                    145:       check_one ("check_onebits", x, y, -1, 0);
                    146:       check_one ("check_onebits", x, -y, 0, 0);
                    147:       mpz_neg (x, x);
                    148:     }
                    149:
                    150:   mpz_clear (x);
                    151:   mpz_clear (x2);
                    152: }
                    153:
                    154:
                    155: /* With the mpz differing by 1, in a limb position possibly below the double */
                    156: void
                    157: check_low_z_one (void)
                    158: {
                    159:   mpz_t          x;
                    160:   double         y;
                    161:   unsigned long  i;
                    162:
                    163:   mpz_init (x);
                    164:
                    165:   /* FIXME: It'd be better to base this on the float format. */
                    166: #ifdef __vax
                    167: #define LIM 127                        /* vax fp numbers have limited range */
                    168: #else
                    169: #define LIM 512
                    170: #endif
                    171:
                    172:   for (i = 1; i < LIM; i++)
                    173:     {
                    174:       mpz_set_ui (x, 1L);
                    175:       mpz_mul_2exp (x, x, i);
                    176:       y = mpz_get_d (x);
                    177:
                    178:       check_one ("check_low_z_one", x, y,   0, 0);
                    179:       check_one ("check_low_z_one", x, -y,  1, 0);
                    180:       mpz_neg (x, x);
                    181:       check_one ("check_low_z_one", x, y,  -1, 0);
                    182:       check_one ("check_low_z_one", x, -y,  0, 0);
                    183:       mpz_neg (x, x);
                    184:
                    185:       mpz_sub_ui (x, x, 1);
                    186:
                    187:       check_one ("check_low_z_one", x, y,  -1, -1);
                    188:       check_one ("check_low_z_one", x, -y,  1, -1);
                    189:       mpz_neg (x, x);
                    190:       check_one ("check_low_z_one", x, y,  -1, -1);
                    191:       check_one ("check_low_z_one", x, -y,  1, -1);
                    192:       mpz_neg (x, x);
                    193:
                    194:       mpz_add_ui (x, x, 2);
                    195:
                    196:       check_one ("check_low_z_one", x, y,   1, 1);
                    197:       check_one ("check_low_z_one", x, -y,  1, 1);
                    198:       mpz_neg (x, x);
                    199:       check_one ("check_low_z_one", x, y,  -1, 1);
                    200:       check_one ("check_low_z_one", x, -y, -1, 1);
                    201:       mpz_neg (x, x);
                    202:     }
                    203:
                    204:   mpz_clear (x);
                    205: }
                    206:
                    207: /* Comparing 1 and 1+2^-n.  "y" is volatile to make gcc store and fetch it,
                    208:    which forces it to a 64-bit double, whereas on x86 it would otherwise
                    209:    remain on the float stack as an 80-bit long double.  */
                    210: void
                    211: check_one_2exp (void)
                    212: {
                    213:   double           e;
                    214:   mpz_t            x;
                    215:   volatile double  y;
                    216:   int              i;
                    217:
                    218:   mpz_init (x);
                    219:
                    220:   e = 1.0;
                    221:   for (i = 0; i < 128; i++)
                    222:     {
                    223:       e /= 2.0;
                    224:       y = 1.0 + e;
                    225:       if (y == 1.0)
                    226:         break;
                    227:
                    228:       mpz_set_ui (x, 1L);
                    229:       check_one ("check_one_2exp", x,  y, -1, -1);
                    230:       check_one ("check_one_2exp", x, -y,  1, -1);
                    231:
                    232:       mpz_set_si (x, -1L);
                    233:       check_one ("check_one_2exp", x,  y, -1, -1);
                    234:       check_one ("check_one_2exp", x, -y,  1, -1);
                    235:     }
                    236:
                    237:   mpz_clear (x);
                    238: }
                    239:
                    240:
                    241: int
                    242: main (int argc, char *argv[])
                    243: {
                    244:   tests_start ();
                    245:
                    246:   check_data ();
                    247:   check_onebits ();
                    248:   check_low_z_one ();
                    249:   check_one_2exp ();
                    250:
                    251:   tests_end ();
                    252:   exit (0);
                    253: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>