home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 247_01 / bndouble.c < prev    next >
Text File  |  1989-04-19  |  3KB  |  143 lines

  1. /*
  2.  *   MIRACL Double to Flash conversion routines - use with care
  3.  *   bndouble.c
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <math.h>
  8. #include "miracl.h"
  9. #define abs(x)  ((x)<0? (-(x)) : (x))
  10. #define sign(x) ((x)<0? (-1) : 1)
  11.  
  12. /* Access global variables */
  13.  
  14. extern int  depth;    /* error tracing .. */
  15. extern int  trace[];  /* .. mechanism     */
  16. extern small base;    /* number base      */
  17. extern int  nib;      /* length of bigs   */
  18. extern int  workprec;
  19. extern bool check;    /* overflow check   */
  20.  
  21. extern big w1;       /* workspace variables  */
  22. extern big w2;
  23. extern big w3;
  24. extern big w4;
  25. extern big w5;
  26. extern big w6;
  27.  
  28. extern double modf();
  29. double D;
  30.  
  31. int dquot(x,num)
  32. flash x;
  33. int num;
  34. { /* generate c.f. for a double D */
  35.     static double b,n,p;
  36.     static int q,oldn;
  37.     int m;
  38.     if (num==0)
  39.     {
  40.         oldn=(-1);
  41.         b=(double)base;
  42.         if (D<1.0)
  43.         {
  44.             D=(1.0/D);
  45.             return (q=0);
  46.         }
  47.     }
  48.     else if (q<0 || num==oldn) return q;
  49.     oldn=num;
  50.     if (D==0.0) return (q=(-1));
  51.     D=modf(D,&n);  /* n is whole number part */
  52.     m=0;           /* D is fractional part (or guard digits!) */
  53.     zero(x);
  54.     while (n>0.0)
  55.     { /* convert n to big */
  56.         m++;
  57.         if (m>nib) return (q=(-2));
  58.         p=n/b;
  59.         modf(p,&p);
  60.         x[m]=n-b*p;
  61.         n=p;
  62.     }
  63.     x[0]=m;
  64.     if (D>0.0) D=(1.0/D);
  65.     return (q=size(x));
  66. }
  67.  
  68. void dconv(d,w)
  69. double d;
  70. flash w;
  71. { /* convert double to rounded flash */
  72.     int s;
  73.     if (ERNUM) return;
  74.     depth++;
  75.     trace[depth]=32;
  76.     if (TRACER) track();
  77.     zero(w);
  78.     if (d==0.0)
  79.     {
  80.         depth--;
  81.         return;
  82.     }
  83.     D=d;
  84.     s=sign(D);
  85.     D=abs(D);
  86.     build(w,dquot);
  87.     insign(s,w);
  88.     depth--;
  89. }
  90.         
  91. double fdsize(w)
  92. flash w;
  93. { /* express flash number as double. */
  94.     int i,s,en,ed;
  95.     double n,d,b;
  96.     if (ERNUM || size(w)==0) return (0.0);
  97.     depth++;
  98.     trace[depth]=11;
  99.     if (TRACER) track();
  100.     EXACT=FALSE;
  101.     n=0.0;
  102.     d=0.0;
  103.     b=(double)base;
  104.     numer(w,w1);
  105.     s=exsign(w1);
  106.     insign(PLUS,w1);
  107.     en=w1[0];
  108.     for (i=1;i<=en;i++)
  109.         n=n/b+w1[i];
  110.     denom(w,w1);
  111.     ed=w1[0];
  112.     for (i=1;i<=ed;i++)
  113.         d=d/b+w1[i];
  114.     n=(s*(n/d));
  115.     while (en!=ed)
  116.     {
  117.         if (en>ed)
  118.         {
  119.             ed++;
  120.             if (BIGGEST/b<n)
  121.             {
  122.                 berror(16);
  123.                 depth--;
  124.                 return (0.0);
  125.             }
  126.             n*=b;
  127.         }
  128.         else
  129.         {
  130.             en++;
  131.             if (n<b/BIGGEST)
  132.             {
  133.                 berror(16);
  134.                 depth--;
  135.                 return (0.0);
  136.             }
  137.             n/=b;
  138.         }
  139.     }
  140.     depth--;
  141.     return n;
  142. }
  143.