/* $Id: pb-div.c 47490 2011-11-10 17:07:08Z vinc17/ypig $ */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gmp.h>
#include <mpfr.h>

int main (int argc, char *argv[])
{
  mpfr_t x, y, q;
  double xd, yd, qd;

  if (argc != 3)
    {
      fprintf (stderr, "Usage: pb-div <x> <y>\n");
      exit (EXIT_FAILURE);
    }

  mpfr_inits2 (53, x, y, q, (void *) 0);

  if (mpfr_set_str (x, argv[1], 0, MPFR_RNDN))
    {
      fprintf (stderr, "pb-div: bad value x (%s)\n", argv[1]);
      exit (EXIT_FAILURE);
    }

  if (mpfr_set_str (y, argv[2], 0, MPFR_RNDN))
    {
      fprintf (stderr, "pb-div: bad value y (%s)\n", argv[1]);
      exit (EXIT_FAILURE);
    }

  xd = mpfr_get_d (x, MPFR_RNDN);
  yd = mpfr_get_d (y, MPFR_RNDN);
  qd = floor (xd / yd);
  printf ("'double' C type:    %.0f\n", qd);

  mpfr_div (q, x, y, MPFR_RNDN);
  mpfr_floor (q, q);
  printf ("double precision:   ");
  mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN);
  putchar ('\n');

  mpfr_set_prec (q, 64);
  mpfr_div (q, x, y, MPFR_RNDN);
  mpfr_floor (q, q);
  printf ("extended precision: ");
  mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN);
  putchar ('\n');

  mpfr_div (q, x, y, MPFR_RNDN);
  mpfr_prec_round (q, 53, MPFR_RNDN);
  mpfr_floor (q, q);
  printf ("extended + double:  ");
  mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN);
  putchar ('\n');

  mpfr_clears (x, y, q, (void *) 0);
  return 0;
}

/*
On Linux/PowerPC and Linux/86 with SSE2 (-march=pentium4 -mfpmath=sse):
$ ./pb-div 42 17
'double' C type:    2
double precision:   2.0000000000000000
extended precision: 2.00000000000000000000
extended + double:  2.0000000000000000
$ ./pb-div 1239 124
'double' C type:    9
double precision:   9.0000000000000000
extended precision: 9.00000000000000000000
extended + double:  9.0000000000000000
$ ./pb-div 13510798882111484 4503599627370495
'double' C type:    2
double precision:   2.0000000000000000
extended precision: 2.00000000000000000000
extended + double:  3.0000000000000000
On Linux/x86 (no SSE2):
$ ./pb-div 42 17
'double' C type:    2
double precision:   2.0000000000000000
extended precision: 2.00000000000000000000
extended + double:  2.0000000000000000
$ ./pb-div 1239 124
'double' C type:    9
double precision:   9.0000000000000000
extended precision: 9.00000000000000000000
extended + double:  9.0000000000000000
$ ./pb-div 13510798882111484 4503599627370495
'double' C type:    3
double precision:   2.0000000000000000
extended precision: 2.00000000000000000000
extended + double:  3.0000000000000000
*/

