[BACK]Return to tmul.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpfr / tests

Annotation of OpenXM_contrib/gmp/mpfr/tests/tmul.c, Revision 1.1.1.1

1.1       ohara       1: /* Test file for mpfr_mul.
                      2:
                      3: Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
                      4:
                      5: This file is part of the MPFR Library.
                      6:
                      7: The MPFR 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 MPFR 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 MPFR 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 <time.h>
                     25: #include "gmp.h"
                     26: #include "gmp-impl.h"
                     27: #include "mpfr.h"
                     28: #include "mpfr-impl.h"
                     29: #include "mpfr-test.h"
                     30:
                     31: void check53 _PROTO((double, double, mp_rnd_t, double));
                     32: void check24 _PROTO((float, float, mp_rnd_t, float));
                     33: void check_float _PROTO((void));
                     34: void check_sign _PROTO((void));
                     35: void check_exact _PROTO((void));
                     36: void check_max _PROTO((void));
                     37: void check_min _PROTO((void));
                     38:
                     39:
                     40: /* Workaround for sparc gcc 2.95.x bug, see notes in tadd.c. */
                     41: #define check(x,y,rnd_mode,px,py,pz,res)  _check(x,y,res,rnd_mode,px,py,pz)
                     42:
                     43: /* checks that x*y gives the same results in double
                     44:    and with mpfr with 53 bits of precision */
                     45: void
                     46: _check (double x, double y, double res, mp_rnd_t rnd_mode, unsigned int px,
                     47:         unsigned int py, unsigned int pz)
                     48: {
                     49:   double z1, z2; mpfr_t xx, yy, zz;
                     50:
                     51:   mpfr_init2 (xx, px);
                     52:   mpfr_init2 (yy, py);
                     53:   mpfr_init2 (zz, pz);
                     54:   mpfr_set_d(xx, x, rnd_mode);
                     55:   mpfr_set_d(yy, y, rnd_mode);
                     56:   mpfr_mul(zz, xx, yy, rnd_mode);
                     57: #ifdef MPFR_HAVE_FESETROUND
                     58:   mpfr_set_machine_rnd_mode(rnd_mode);
                     59: #endif
                     60:   z1 = (res==0.0) ? x*y : res;
                     61:   z2 = mpfr_get_d1 (zz);
                     62:   if (z1!=z2 && (z1>=MINNORM || z1<=-MINNORM)) {
                     63:     printf("mpfr_mul ");
                     64:     if (res==0.0) printf("differs from libm.a"); else printf("failed");
                     65:       printf(" for x=%1.20e y=%1.20e with rnd_mode=%s\n", x, y,
                     66:             mpfr_print_rnd_mode(rnd_mode));
                     67:     printf("libm.a gives %1.20e, mpfr_mul gives %1.20e\n", z1, z2);
                     68:     if (res!=0.0) exit(1);
                     69:   }
                     70:   mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
                     71: }
                     72:
                     73: void
                     74: check53 (double x, double y, mp_rnd_t rnd_mode, double z1)
                     75: {
                     76:   double z2; mpfr_t xx, yy, zz;
                     77:
                     78:   mpfr_init2 (xx, 53);
                     79:   mpfr_init2 (yy, 53);
                     80:   mpfr_init2 (zz, 53);
                     81:   mpfr_set_d (xx, x, rnd_mode);
                     82:   mpfr_set_d (yy, y, rnd_mode);
                     83:   mpfr_mul (zz, xx, yy, rnd_mode);
                     84:   z2 = mpfr_get_d1 (zz);
                     85:   if (z1!=z2 && (!isnan(z1) || !isnan(z2))) {
                     86:     printf("mpfr_mul failed for x=%1.20e y=%1.20e with rnd_mode=%s\n",
                     87:           x, y, mpfr_print_rnd_mode(rnd_mode));
                     88:     printf("libm.a gives %1.20e, mpfr_mul gives %1.20e\n", z1, z2);
                     89:     exit(1);
                     90:   }
                     91:   mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
                     92: }
                     93:
                     94: /* checks that x*y gives the same results in double
                     95:    and with mpfr with 24 bits of precision */
                     96: void
                     97: check24 (float x, float y, mp_rnd_t rnd_mode, float z1)
                     98: {
                     99:   float z2;
                    100:   mpfr_t xx, yy, zz;
                    101:
                    102:   mpfr_init2 (xx, 24);
                    103:   mpfr_init2 (yy, 24);
                    104:   mpfr_init2 (zz, 24);
                    105:   mpfr_set_d (xx, x, rnd_mode);
                    106:   mpfr_set_d (yy, y, rnd_mode);
                    107:   mpfr_mul (zz, xx, yy, rnd_mode);
                    108:   z2 = (float) mpfr_get_d1 (zz);
                    109:   if (z1 != z2)
                    110:     {
                    111:       fprintf (stderr, "mpfr_mul failed for x=%1.0f y=%1.0f with prec=24 and"
                    112:              "rnd=%s\n", x, y, mpfr_print_rnd_mode(rnd_mode));
                    113:       fprintf (stderr, "libm.a gives %.10e, mpfr_mul gives %.10e\n", z1, z2);
                    114:       exit (1);
                    115:     }
                    116:   mpfr_clear(xx);
                    117:   mpfr_clear(yy);
                    118:   mpfr_clear(zz);
                    119: }
                    120:
                    121: /* the following examples come from the paper "Number-theoretic Test
                    122:    Generation for Directed Rounding" from Michael Parks, Table 1 */
                    123: void
                    124: check_float (void)
                    125: {
                    126:   float z;
                    127:
                    128:   check24(8388609.0,  8388609.0, GMP_RNDN, 70368760954880.0);
                    129:   check24(16777213.0, 8388609.0, GMP_RNDN, 140737479966720.0);
                    130:   check24(8388611.0,  8388609.0, GMP_RNDN, 70368777732096.0);
                    131:   check24(12582911.0, 8388610.0, GMP_RNDN, 105553133043712.0);
                    132:   check24(12582914.0, 8388610.0, GMP_RNDN, 105553158209536.0);
                    133:   check24(13981013.0, 8388611.0, GMP_RNDN, 117281279442944.0);
                    134:   check24(11184811.0, 8388611.0, GMP_RNDN, 93825028587520.0);
                    135:   check24(11184810.0, 8388611.0, GMP_RNDN, 93825020198912.0);
                    136:   check24(13981014.0, 8388611.0, GMP_RNDN, 117281287831552.0);
                    137:
                    138:   check24(8388609.0,  8388609.0, GMP_RNDZ, 70368760954880.0);
                    139:   check24(16777213.0, 8388609.0, GMP_RNDZ, 140737471578112.0);
                    140:   z = 70368777732096.0;
                    141:   check24(8388611.0,  8388609.0, GMP_RNDZ, z);
                    142:   check24(12582911.0, 8388610.0, GMP_RNDZ, 105553124655104.0);
                    143:   check24(12582914.0, 8388610.0, GMP_RNDZ, 105553158209536.0);
                    144:   check24(13981013.0, 8388611.0, GMP_RNDZ, 117281271054336.0);
                    145:   check24(11184811.0, 8388611.0, GMP_RNDZ, 93825028587520.0);
                    146:   check24(11184810.0, 8388611.0, GMP_RNDZ, 93825011810304.0);
                    147:   check24(13981014.0, 8388611.0, GMP_RNDZ, 117281287831552.0);
                    148:
                    149:   check24(8388609.0,  8388609.0, GMP_RNDU, 70368769343488.0);
                    150:   check24(16777213.0, 8388609.0, GMP_RNDU, 140737479966720.0);
                    151:   check24(8388611.0,  8388609.0, GMP_RNDU, 70368786120704.0);
                    152:   check24(12582911.0, 8388610.0, GMP_RNDU, 105553133043712.0);
                    153:   check24(12582914.0, 8388610.0, GMP_RNDU, 105553166598144.0);
                    154:   check24(13981013.0, 8388611.0, GMP_RNDU, 117281279442944.0);
                    155:   check24(11184811.0, 8388611.0, GMP_RNDU, 93825036976128.0);
                    156:   check24(11184810.0, 8388611.0, GMP_RNDU, 93825020198912.0);
                    157:   check24(13981014.0, 8388611.0, GMP_RNDU, 117281296220160.0);
                    158:
                    159:   check24(8388609.0,  8388609.0, GMP_RNDD, 70368760954880.0);
                    160:   check24(16777213.0, 8388609.0, GMP_RNDD, 140737471578112.0);
                    161:   check24(8388611.0,  8388609.0, GMP_RNDD, 70368777732096.0);
                    162:   check24(12582911.0, 8388610.0, GMP_RNDD, 105553124655104.0);
                    163:   check24(12582914.0, 8388610.0, GMP_RNDD, 105553158209536.0);
                    164:   check24(13981013.0, 8388611.0, GMP_RNDD, 117281271054336.0);
                    165:   check24(11184811.0, 8388611.0, GMP_RNDD, 93825028587520.0);
                    166:   check24(11184810.0, 8388611.0, GMP_RNDD, 93825011810304.0);
                    167:   check24(13981014.0, 8388611.0, GMP_RNDD, 117281287831552.0);
                    168: }
                    169:
                    170: /* check sign of result */
                    171: void
                    172: check_sign (void)
                    173: {
                    174:   mpfr_t a, b;
                    175:
                    176:   mpfr_init2 (a, 53);
                    177:   mpfr_init2 (b, 53);
                    178:   mpfr_set_d(a, -1.0, GMP_RNDN);
                    179:   mpfr_set_d(b, 2.0, GMP_RNDN);
                    180:   mpfr_mul(a, b, b, GMP_RNDN);
                    181:   if (mpfr_get_d1 (a) != 4.0) {
                    182:     fprintf(stderr,"2.0*2.0 gives %1.20e\n", mpfr_get_d1 (a)); exit(1);
                    183:   }
                    184:   mpfr_clear(a); mpfr_clear(b);
                    185: }
                    186:
                    187: /* checks that the inexact return value is correct */
                    188: void
                    189: check_exact (void)
                    190: {
                    191:   mpfr_t a, b, c, d;
                    192:   mp_prec_t prec;
                    193:   int i, inexact;
                    194:   mp_rnd_t rnd;
                    195:
                    196:   mpfr_init (a);
                    197:   mpfr_init (b);
                    198:   mpfr_init (c);
                    199:   mpfr_init (d);
                    200:
                    201:   mpfr_set_prec (a, 17);
                    202:   mpfr_set_prec (b, 17);
                    203:   mpfr_set_prec (c, 32);
                    204:   mpfr_set_str_raw (a, "1.1000111011000100e-1");
                    205:   mpfr_set_str_raw (b, "1.0010001111100111e-1");
                    206:   if (mpfr_mul (c, a, b, GMP_RNDZ))
                    207:     {
                    208:       fprintf (stderr, "wrong return value (1)\n");
                    209:       exit (1);
                    210:     }
                    211:
                    212:   for (prec = 2; prec < 100; prec++)
                    213:     {
                    214:       mpfr_set_prec (a, prec);
                    215:       mpfr_set_prec (b, prec);
                    216:       mpfr_set_prec (c, 2 * prec - 2);
                    217:       mpfr_set_prec (d, 2 * prec);
                    218:       for (i = 0; i < 1000; i++)
                    219:        {
                    220:          mpfr_random (a);
                    221:          mpfr_random (b);
                    222:          rnd = LONG_RAND() % 4;
                    223:          inexact = mpfr_mul (c, a, b, rnd);
                    224:          if (mpfr_mul (d, a, b, rnd)) /* should be always exact */
                    225:            {
                    226:              fprintf (stderr, "unexpected inexact return value\n");
                    227:              exit (1);
                    228:            }
                    229:          if ((inexact == 0) && mpfr_cmp (c, d))
                    230:            {
                    231:              fprintf (stderr, "inexact=0 but results differ\n");
                    232:              exit (1);
                    233:            }
                    234:          else if (inexact && (mpfr_cmp (c, d) == 0))
                    235:            {
                    236:              fprintf (stderr, "inexact!=0 but results agree\n");
                    237:              fprintf (stderr, "prec=%u rnd=%s a=", (unsigned int) prec,
                    238:                       mpfr_print_rnd_mode (rnd));
                    239:              mpfr_out_str (stderr, 2, 0, a, rnd);
                    240:              fprintf (stderr, "\nb=");
                    241:              mpfr_out_str (stderr, 2, 0, b, rnd);
                    242:              fprintf (stderr, "\nc=");
                    243:              mpfr_out_str (stderr, 2, 0, c, rnd);
                    244:              fprintf (stderr, "\nd=");
                    245:              mpfr_out_str (stderr, 2, 0, d, rnd);
                    246:              fprintf (stderr, "\n");
                    247:              exit (1);
                    248:            }
                    249:        }
                    250:     }
                    251:
                    252:   mpfr_clear (a);
                    253:   mpfr_clear (b);
                    254:   mpfr_clear (c);
                    255:   mpfr_clear (d);
                    256: }
                    257:
                    258: void
                    259: check_max(void)
                    260: {
                    261:   mpfr_t xx, yy, zz;
                    262:
                    263:   mpfr_init2(xx, 4);
                    264:   mpfr_init2(yy, 4);
                    265:   mpfr_init2(zz, 4);
                    266:   mpfr_set_d(xx, 11.0/16, GMP_RNDN);
                    267:   mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT/2, GMP_RNDN);
                    268:   mpfr_set_d(yy, 11.0/16, GMP_RNDN);
                    269:   mpfr_mul_2si(yy, yy, MPFR_EMAX_DEFAULT - MPFR_EMAX_DEFAULT/2 + 1, GMP_RNDN);
                    270:   mpfr_clear_flags();
                    271:   mpfr_mul(zz, xx, yy, GMP_RNDU);
                    272:   if (!(mpfr_overflow_p() && MPFR_IS_INF(zz)))
                    273:     {
                    274:       printf("check_max failed (should be an overflow)\n");
                    275:       exit(1);
                    276:     }
                    277:
                    278:   mpfr_clear_flags();
                    279:   mpfr_mul(zz, xx, yy, GMP_RNDD);
                    280:   if (mpfr_overflow_p() || MPFR_IS_INF(zz))
                    281:     {
                    282:       printf("check_max failed (should NOT be an overflow)\n");
                    283:       exit(1);
                    284:     }
                    285:   mpfr_set_d(xx, 15.0/16, GMP_RNDN);
                    286:   mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT, GMP_RNDN);
                    287:   if (!(MPFR_IS_FP(xx) && MPFR_IS_FP(zz)))
                    288:     {
                    289:       printf("check_max failed (internal error)\n");
                    290:       exit(1);
                    291:     }
                    292:   if (mpfr_cmp(xx, zz) != 0)
                    293:     {
                    294:       printf("check_max failed: got ");
                    295:       mpfr_out_str(stdout, 2, 0, zz, GMP_RNDZ);
                    296:       printf(" instead of ");
                    297:       mpfr_out_str(stdout, 2, 0, xx, GMP_RNDZ);
                    298:       printf("\n");
                    299:       exit(1);
                    300:     }
                    301:
                    302:   mpfr_clear(xx);
                    303:   mpfr_clear(yy);
                    304:   mpfr_clear(zz);
                    305: }
                    306:
                    307: void
                    308: check_min(void)
                    309: {
                    310:   mpfr_t xx, yy, zz;
                    311:
                    312:   mpfr_init2(xx, 4);
                    313:   mpfr_init2(yy, 4);
                    314:   mpfr_init2(zz, 3);
                    315:   mpfr_set_d(xx, 15.0/16, GMP_RNDN);
                    316:   mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT/2, GMP_RNDN);
                    317:   mpfr_set_d(yy, 15.0/16, GMP_RNDN);
                    318:   mpfr_mul_2si(yy, yy, MPFR_EMIN_DEFAULT - MPFR_EMIN_DEFAULT/2 - 1, GMP_RNDN);
                    319:   mpfr_mul(zz, xx, yy, GMP_RNDD);
                    320:   if (mpfr_sgn(zz) != 0)
                    321:     {
                    322:       printf("check_min failed: got ");
                    323:       mpfr_out_str(stdout, 2, 0, zz, GMP_RNDZ);
                    324:       printf(" instead of 0\n");
                    325:       exit(1);
                    326:     }
                    327:
                    328:   mpfr_mul(zz, xx, yy, GMP_RNDU);
                    329:   mpfr_set_d(xx, 0.5, GMP_RNDN);
                    330:   mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT, GMP_RNDN);
                    331:   if (mpfr_sgn(xx) <= 0)
                    332:     {
                    333:       printf("check_min failed (internal error)\n");
                    334:       exit(1);
                    335:     }
                    336:   if (mpfr_cmp(xx, zz) != 0)
                    337:     {
                    338:       printf("check_min failed: got ");
                    339:       mpfr_out_str(stdout, 2, 0, zz, GMP_RNDZ);
                    340:       printf(" instead of ");
                    341:       mpfr_out_str(stdout, 2, 0, xx, GMP_RNDZ);
                    342:       printf("\n");
                    343:       exit(1);
                    344:     }
                    345:
                    346:   mpfr_clear(xx);
                    347:   mpfr_clear(yy);
                    348:   mpfr_clear(zz);
                    349: }
                    350:
                    351: int
                    352: main (int argc, char *argv[])
                    353: {
                    354: #ifdef MPFR_HAVE_FESETROUND
                    355:   double x, y, z;
                    356:   int i, prec, rnd_mode;
                    357:
                    358:   mpfr_test_init ();
                    359: #endif
                    360:
                    361:   check_exact ();
                    362:   check_float ();
                    363: #ifdef HAVE_INFS
                    364:   check53 (0.0, DBL_POS_INF, GMP_RNDN, DBL_NAN);
                    365:   check53(1.0, DBL_POS_INF, GMP_RNDN, DBL_POS_INF);
                    366:   check53(-1.0, DBL_POS_INF, GMP_RNDN, DBL_NEG_INF);
                    367:   check53(DBL_NAN, 0.0, GMP_RNDN, DBL_NAN);
                    368:   check53(1.0, DBL_NAN, GMP_RNDN, DBL_NAN);
                    369: #endif
                    370:   check53(6.9314718055994530941514e-1, 0.0, GMP_RNDZ, 0.0);
                    371:   check53(0.0, 6.9314718055994530941514e-1, GMP_RNDZ, 0.0);
                    372:   check_sign();
                    373:   check53(-4.165000000e4, -0.00004801920768307322868063274915, GMP_RNDN, 2.0);
                    374:   check53(2.71331408349172961467e-08, -6.72658901114033715233e-165, GMP_RNDZ,
                    375:          -1.8251348697787782844e-172);
                    376:   check53(0.31869277231188065, 0.88642843322303122, GMP_RNDZ,
                    377:          2.8249833483992453642e-1);
                    378:   check(8.47622108205396074254e-01, 3.24039313247872939883e-01, GMP_RNDU,
                    379:        28, 45, 2, 0.375);
                    380:   check(2.63978122803639081440e-01, 6.8378615379333496093e-1, GMP_RNDN,
                    381:        34, 23, 31, 0.180504585267044603);
                    382:   check(1.0, 0.11835170935876249132, GMP_RNDU, 6, 41, 36, 0.1183517093595583);
                    383:   check53(67108865.0, 134217729.0, GMP_RNDN, 9.007199456067584e15);
                    384:   check(1.37399642157394197284e-01, 2.28877275604219221350e-01, GMP_RNDN,
                    385:        49, 15, 32, 0.0314472340833162888);
                    386:   check(4.03160720978664954828e-01, 5.85483042917246621073e-01, GMP_RNDZ,
                    387:        51, 22, 32, 0.2360436821472831);
                    388:   check(3.90798504668055102229e-14, 9.85394674650308388664e-04, GMP_RNDN,
                    389:        46, 22, 12, 0.385027296503914762e-16);
                    390:   check(4.58687081072827851358e-01, 2.20543551472118792844e-01, GMP_RNDN,
                    391:        49, 3, 2, 0.09375);
                    392:   check_max();
                    393:   check_min();
                    394: #ifdef MPFR_HAVE_FESETROUND
                    395:   SEED_RAND (time(NULL));
                    396:   prec = (argc<2) ? 53 : atoi(argv[1]);
                    397:   rnd_mode = (argc<3) ? -1 : atoi(argv[2]);
                    398:   for (i=0;i<1000000;) {
                    399:     x = drand();
                    400:     y = drand();
                    401:     z = x*y; if (z<0) z=-z;
                    402:     if (z<1e+308 && z>1e-308) /* don't test overflow/underflow for now */
                    403:       { i++;
                    404:       check(x, y, (rnd_mode==-1) ? LONG_RAND()%4 : rnd_mode,
                    405:            prec, prec, prec, 0.0);
                    406:       }
                    407:   }
                    408: #endif
                    409:
                    410:   return 0;
                    411: }

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