Home | History | Annotate | Line # | Download | only in mpf
t-ui_div.c revision 1.1
      1 /* Test mpf_ui_div.
      2 
      3 Copyright 2004 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 3 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.  If not, see http://www.gnu.org/licenses/.  */
     19 
     20 #include <stdio.h>
     21 #include <stdlib.h>
     22 #include "gmp.h"
     23 #include "gmp-impl.h"
     24 #include "tests.h"
     25 
     26 
     27 void
     28 check_one (const char *desc, mpf_ptr got, unsigned long u, mpf_srcptr v)
     29 {
     30   mpf_t      uf;
     31   mp_limb_t  ulimbs[2];
     32   mp_size_t  usize;
     33 
     34   ulimbs[0] = u & GMP_NUMB_MASK;
     35   usize = (u != 0);
     36 #if BITS_PER_ULONG > GMP_NUMB_BITS
     37   u >>= GMP_NUMB_BITS;
     38   ulimbs[1] = u;
     39   usize += (u != 0);
     40 #endif
     41   PTR(uf) = ulimbs;
     42   SIZ(uf) = usize;
     43   EXP(uf) = usize;
     44 
     45   if (! refmpf_validate_division ("mpf_ui_div", got, uf, v))
     46     {
     47       mp_trace_base = -16;
     48       printf    ("  u 0x%lX  (%lu)\n", u, u);
     49       mpf_trace ("  v", v);
     50       printf    ("  %s\n", desc);
     51       abort ();
     52     }
     53 }
     54 
     55 void
     56 check_rand (void)
     57 {
     58   unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
     59   gmp_randstate_ptr  rands = RANDS;
     60   unsigned long  prec, u;
     61   mpf_t  got, v;
     62   int    i;
     63 
     64   mpf_init (got);
     65   mpf_init (v);
     66 
     67   for (i = 0; i < 200; i++)
     68     {
     69       /* got precision */
     70       prec = min_prec + gmp_urandomm_ui (rands, 15L);
     71       refmpf_set_prec_limbs (got, prec);
     72 
     73       /* u */
     74       prec = gmp_urandomm_ui (rands, BITS_PER_ULONG+1);
     75       u = gmp_urandomb_ui (rands, prec);
     76 
     77       /* v precision */
     78       prec = min_prec + gmp_urandomm_ui (rands, 15L);
     79       refmpf_set_prec_limbs (v, prec);
     80 
     81       /* v, non-zero */
     82       do {
     83         mpf_random2 (v, PREC(v), (mp_exp_t) 20);
     84       } while (SIZ(v) == 0);
     85 
     86       /* v possibly negative */
     87       if (gmp_urandomb_ui (rands, 1L))
     88         mpf_neg (v, v);
     89 
     90       if ((i % 2) == 0)
     91         {
     92           /* src != dst */
     93           mpf_ui_div (got, u, v);
     94           check_one ("separate", got, u, v);
     95         }
     96       else
     97         {
     98           /* src == dst */
     99           prec = refmpf_set_overlap (got, v);
    100           mpf_ui_div (got, u, got);
    101           check_one ("overlap src==dst", got, u, v);
    102 
    103           mpf_set_prec_raw (got, prec);
    104         }
    105     }
    106 
    107   mpf_clear (got);
    108   mpf_clear (v);
    109 }
    110 
    111 void
    112 check_various (void)
    113 {
    114   mpf_t got, v;
    115 
    116   mpf_init (got);
    117   mpf_init (v);
    118 
    119   /* 100/4 == 25 */
    120   mpf_set_prec (got, 20L);
    121   mpf_set_ui (v, 4L);
    122   mpf_ui_div (got, 100L, v);
    123   MPF_CHECK_FORMAT (got);
    124   ASSERT_ALWAYS (mpf_cmp_ui (got, 25L) == 0);
    125 
    126   {
    127     /* 1/(2^n+1), a case where truncating the divisor would be wrong */
    128     unsigned long  u = 1L;
    129     mpf_set_prec (got, 500L);
    130     mpf_set_prec (v, 900L);
    131     mpf_set_ui (v, 1L);
    132     mpf_mul_2exp (v, v, 800L);
    133     mpf_add_ui (v, v, 1L);
    134     mpf_ui_div (got, u, v);
    135     check_one ("1/2^n+1, separate", got, u, v);
    136   }
    137 
    138   mpf_clear (got);
    139   mpf_clear (v);
    140 }
    141 
    142 int
    143 main (void)
    144 {
    145   tests_start ();
    146 
    147   check_various ();
    148   check_rand ();
    149 
    150   tests_end ();
    151   exit (0);
    152 }
    153