Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Cephes/qfloat/   (Cephes Mathematical Library ©)  Datei vom 12.5.2026 mit Größe 34 kB image not shown  

Quelle  qflt.c   Sprache: C

 

/* qflt.c
 *   QFLOAT
 *
 * Extended precision floating point routines
 *
 * asctoq( string, q ) ascii string to q type
 * dtoq( &d, q )  DEC double precision to q type
 * etoq( &d, q )  IEEE double precision to q type
 * e24toq( &d, q )  IEEE single precision to q type
 * e113toq( &d, q ) 128-bit long double precision to q type
 * ltoq( &l, q )  long integer to q type
 * qabs(q)   absolute value
 * qadd( a, b, c )  c = b + a
 * qclear(q)  q = 0
 * qcmp( a, b )  compare a to b
 * qdiv( a, b, c )  c = b / a
 * qifrac( x, &l, frac )   x to integer part l and q type fraction
 * qfrexp( x, l, y ) find exponent l and fraction y between .5 and 1
 * qldexp( x, l, y ) multiply x by 2^l
 * qinfin( x )  set x to infinity, leaving its sign alone
 * qmov( a, b )  b = a
 * qmul( a, b, c )  c = b * a
 * qmuli( a, b, c ) c = b * a, a has only 16 significant bits
 * qisneg(q)  returns sign of q
 * qneg(q)   q = -q
 * qnrmlz(q)  adjust exponent and mantissa
 * qsub( a, b, c )  c = b - a
 * qtoasc( a, s, n ) q to ASCII string, n digits after decimal
 * qtod( q, &d )  convert q type to DEC double precision
 * qtoe( q, &d )  convert q type to IEEE double precision
 * qtoe24( q, &d )  convert q type to IEEE single precision
 * qtoe113( q, &d ) convert q type to 128-bit long double precision
 *
 * Data structure of the number (a "word" is 16 bits)
 *
 * sign word  (0 for positive, -1 for negative)
 * exponent  (EXPONE for 1.0)
 * high guard word  (always zero after normalization)
 * N-1 mantissa words (most significant word first,
 *     most significant bit is set)
 *
 * Numbers are stored in C language as arrays.  All routines
 * use pointers to the arrays as arguments.
 *
 * The result is always normalized after each arithmetic operation.
 * All arithmetic results are chopped. No rounding is performed except
 * on conversion to double precision.
 */


/*
 * Revision history:
 *
 * SLM,  5 Jan 84 PDP-11 assembly language version
 * SLM,  2 Mar 86 fixed bug in asctoq()
 * SLM,  6 Dec 86 C language version
 *
 */


#include <stdio.h>
#include "mconf.h"
#include "qhead.h"

#ifdef UNK
#if BIGENDIAN
#define MIEEE
#else
#define IBMPC
#endif
#undef UNK
#endif

 /* number of 16 bit words in mantissa area */
/*define N 10*/
 /* max number of decimal digits in conversion */
/*define NDEC 46*/
 /* number of bits of precision */
/*define NBITS (OMG-1)*16*/
/* array index of the sign (a whole int wasted) */
#define SIGNWORD 0
/* array index of the exponent */
#define E 1
/* array index of first mantissa word */
#define M 2

/* Define 1 for sticky bit rounding */
#ifndef STICKY
#define STICKY 0
#endif

 /* accumulators */
static QELT ac1[NQ+1];
static QELT ac2[NQ+1];
static QELT ac3[NQ+1];
static QELT ac4[NQ+1];
 /* shift count register */
static int SC;

extern QELT qzero[], qone[];

#ifdef ANSIPROT
int shdn1( QELT * ), shup1( QELT * ), shdn8( QELT * ), shup8( QELT * );
int shdn16( QELT * ), shup16( QELT * );
int mulm( QELT *, QELT * ), mulin( QELT *, QELT * ), divn( QELT *, QELT * );
int qmovz( QELT *, QELT * ), normlz( QELT * ), cmpm( QELT *, QELT * );
int addm( QELT *, QELT * ), subm( QELT *, QELT * ), shift( QELT * );
int qadd1( QELT *, QELT *, QELT * );
#else
int shdn1(), shup1(), shdn8(), shup8(), shdn16(), shup16();
int mulm(), mulin(), divm(), qmovz(), normlz();
int cmpm(), addm(), subm(), qadd1(), shift();
#endif

/*
; Absolute value
;
; QELT q[NQ];
; qabs( q );
*/


int qabs(x)
QELT x[];
{
  x[SIGNWORD] = 0;
  return  0;
}


/* Test if negative  */

int qisneg(x)
QELT *x;
{
return (x[SIGNWORD] != 0);
}

/*
; Negate
;
; short q[NQ];
; qneg( q );
*/


int qneg(x)
QELT *x;
{

*x = ~(*x); /* complement the sign */
return 0;
}

/*
; convert long (32-bit) integer to q type
;
; long l;
; QELT q[NQ];
; ltoq( &l, q );
; note &l is the memory address of l
*/


int ltoq( lp, y )
long *lp;
QELT y[];
{
register QELT *p; /* use processor registers if possible */
long ll;

qclear( ac1 );
ll = *lp;  /* local copy of lp */
if( ll < 0 )
 {
 ll = -ll; /* make it positive */
 ac1[SIGNWORD] = -1; /* put correct sign in the q type number */
 }

/* move the long integer to ac1 mantissa area */
p = &ac1[M];
*p++ = ll >> 16;
*p = ll;
/*
 * q = (short *)&ll;
 * #if DEC
 * p = &ac1[M];
 * *p++ = *q++;
 * #endif
 * #if IBMPC
 * p = &ac1[M+1];
 * *p-- = *q++;
 * #endif
 * *p = *q;
 */

ac1[E] = EXPONE+15; /* exponent if normalize shift count were 0 */
ac1[NQ] = 0;
if( normlz( ac1 ) ) /* normalize the mantissa */
 qclear( ac1 ); /* it was zero */
else
 ac1[E] -= SC; /* else subtract shift count from exponent */
qmov( ac1, y );  /* output the answer */
return 0;
}

/*
; convert DEC double precision to q type
; double d;
; QELT q[NQ];
; dtoq( &d, q );
*/

int dtoq( d, y )
unsigned short *d;
QELT *y;
{
register QELT r, *p;

qclear(y);  /* start with a zero */
p = y;   /* point to our number */
r = *d;   /* get DEC exponent word */
if( r & 0x8000 )
 *p = -1; /* fill in our sign */
++p;   /* bump pointer to our exponent word */
r &= 0x7fff;  /* strip the sign bit */
if( r == 0 )  /* answer = 0 if high order DEC word = 0 */
 return 0;


r >>= 7; /* shift exponent word down 7 bits */
r -= 0200; /* subtract DEC exponent offset */
r += EXPONE - 1; /* add our q type exponent offset */
*p++ = r; /* to form our exponent */

r = *d++; /* now do the high order mantissa */
r &= 0177; /* strip off the DEC exponent and sign bits */
r |= 0200; /* the DEC understood high order mantissa bit */
*p++ = r; /* put result in our high guard word */

*p++ = *d++; /* fill in the rest of our mantissa */
*p++ = *d++;
*p = *d;

shdn8(y); /* shift our mantissa down 8 bits */
return 0;
}

/*
; convert q type to DEC double precision
; double d;
; QELT q[NQ];
; qtod( q, &d );
*/


int qtod( x, d )
QELT *x;
unsigned short *d;
{
register int r;
int i, j;

*d = 0;
if( *x != 0 )
 *d = 0100000;
qmovz( x, ac1 );
r = ac1[E];
if( r < (EXPONE - 1 - 0200) )
 goto zout;
i = ac1[M+4];
if( (i & 0200) != 0 )
 {
 if( (i & 0377) == 0200 )
  {
  if( (i & 0400) != 0 )
   {
  /* check all less significant bits */
   for( j=M+5; j<=NQ; j++ )
    {
    if( ac1[j] != 0 )
     goto yesrnd;
    }
   }
  goto nornd;
  }
yesrnd:
 qclear( ac2 );
 ac2[ M+4 ] = 0200;
 ac2[NQ] = 0;
 addm( ac2, ac1 );
 normlz(ac1);
 r -= SC;
 }

nornd:

r -= EXPONE - 1;
r += 0200;
if( r < 0 )
 {
zout:
 *d++ = 0;
 *d++ = 0;
 *d++ = 0;
 *d++ = 0;
 return 0;
 }
if( r >= 0377 )
 {
 *d++ = 077777;
 *d++ = -1;
 *d++ = -1;
 *d++ = -1;
 return 0;
 }
r &= 0377;
r <<= 7;
shup8( ac1 );
ac1[M] &= 0177;
r |= ac1[M];
*d++ |= r;
*d++ = ac1[M+1];
*d++ = ac1[M+2];
*d++ = ac1[M+3];
return 0;
}

/*
; Find integer and fractional parts

; long i;
; QELT x[NQ], frac[NQ];
; qifrac( x, &i, frac );
*/


int qifrac( x, i, frac )
QELT x[];
long *i;
QELT frac[];
{

qmovz( x, ac1 );
SC = ac1[E] - (EXPONE - 1);
if( SC <= 0 )
 {
/* if exponent <= 0, integer = 0 and argument is fraction */
 *i = 0L;
 qmov( ac1, frac );
 return 0;
 }
if( SC > 31 )
 {
/*
; long integer overflow: output large integer
; and correct fraction
*/

 *i = 0x7fffffff;
 shift( ac1 );
 goto lab10;
 }

if( SC > 16 )
 {
/*
; shift more than 16 bits: shift up SC-16, output the integer,
; then complete the shift to get the fraction.
*/

 SC -= 16;
 shift( ac1 );
 *i = ((unsigned long )ac1[M] << 16) | (unsigned short )ac1[M+1];
/*
 *  p = (short *)i;
 * #ifdef DEC
 *  *p++ = ac1[M];
 *  *p++ = ac1[M+1];
 * #else
 *  *p++ = ac1[M+1];
 *  *p++ = ac1[M];
 * #endif
 */

 shup16( ac1 );
 goto lab10;
 }

/* shift not more than 16 bits */
shift( ac1 );
*i = ac1[M] & 0xffff;

lab10:
if( x[SIGNWORD] )
 *i = -(*i);
ac1[SIGNWORD] = 0;
ac1[E] = EXPONE - 1;
ac1[M] = 0;
if( normlz(ac1) )
 qclear( ac1 );
else
 ac1[E] -= SC;

qmov( ac1, frac );
return 0;
}

int qldexp( x, n, y)
QELT *x;
long n;
QELT *y;
{
long k;

k = (long) x[E]  +  n;
qmov( x, y );
y[E] = k;
if( (k > MAXEXP) || (n > (2 * (long)MAXEXP)) )
        qinfin(y);
if( (k <= 0) || (n < (-2 * (long)MAXEXP)) )
        qclear(y);
return(0);
}


int qfrexp (x, e, y)
QELT *x;
long *e;
QELT *y;
{

if( x[E] == 0 )
 {
 *e = 0;
 qclear(y);
 }
else
 {
 *e = (long) x[E] - (long) EXPONE + 1;
 qmov( x, y );
 y[1] = EXPONE - 1;
 }
return 0;
}

/*
; subtract
;
; QELT a[NQ], b[NQ], c[NQ];
; qsub( a, b, c );  c = b - a
*/


static short subflg = 0;

int qsub( a, b, c )
QELT *a, *b, *c;
{

subflg = 1;
qadd1( a, b, c );
return 0;
}


/*
; add
;
; QELT a[NQ], b[NQ], c[NQ];
; qadd( a, b, c );  c = b + a
*/


int qadd( a, b, c )
QELT *a, *b, *c;
{

subflg = 0;
qadd1( a, b, c );
return 0;
}

int qadd1( a, b, c )
QELT *a, *b, *c;
{
long lt;
int i;
#if STICKY
int lost;
#endif

qmovz( a, ac1 );
qmovz( b, ac2 );
if( subflg )
 ac1[SIGNWORD] = ~ac1[SIGNWORD];

/* compare exponents */
lt = (long) ac1[E] - (long) ac2[E]; 
if( lt > 0 )
 { /* put the larger number in ac2 */
 qmovz( ac2, ac3 );
 qmov( ac1, ac2 );
 qmov( ac3, ac1 );
 lt = -lt;
 }
SC = lt;
#if STICKY
lost = 0;
#endif
if( lt != 0 )
 {
 if( lt < -NBITS-1 )
  goto done; /* answer same as larger addend */

#if STICKY
 lost = shift( ac1 ); /* shift the smaller number down */
#else
 shift( ac1 ); /* shift the smaller number down */
#endif
 }
else
 {
/* exponents were the same, so must compare mantissae */
 i = cmpm( ac1, ac2 );
 if( i == 0 )
  { /* the numbers are identical */
  /* if different signs, result is zero */
  if( ac1[SIGNWORD] != ac2[SIGNWORD] )
   goto underf;
  /* if exponents zero, result is zero */
  if( ac1[E] == 0 )
   goto underf;
  /* if same sign, result is double */
  if( ac1[E] >= MAXEXP )
   {
   qclear(c);
   if( ac1[SIGNWORD] != 0 )
    qneg(c);
   goto overf;
   }
  ac2[E] += 1;
  goto done;
  }
 if( i > 0 )
  { /* put the larger number in ac2 */
  qmovz( ac2, ac3 );
  qmov( ac1, ac2 );
  qmov( ac3, ac1 );
  }
 }

if( ac1[SIGNWORD] == ac2[SIGNWORD] )
 {
 addm( ac1, ac2 );
 subflg = 0;
 }
else
 {
 subm( ac1, ac2 );
 subflg = 1;
 }
if( normlz(ac2) )
 goto underf;

lt = (long )ac2[E] - SC;
if( lt > MAXEXP )
 goto overf;
if( lt < 0 )
 {
/* mtherr( "qadd", UNDERFLOW );*/
 goto underf; 
 }
ac2[E] = lt;

/* round off */
i = ac2[NQ] & 0xffff;
if( i & SIGNBIT )
 {
#if STICKY
 if( i == SIGNBIT )
  {
  if( lost == 0 )
   {
/* Critical case, round to even */
   if( (ac2[NQ-1] & 1) == 0 )
    goto done;
   }
  else
   {
   if( subflg != 0 )
    goto done;
   }
  }
#else
 if( subflg != 0 )
  goto done;
#endif
 
 qclear( ac1 );
 ac1[NQ] = 0;
 ac1[NQ-1] = 1;
 addm( ac1, ac2 );
 normlz(ac2);
 if( SC )
  {
  lt = (long )ac2[E] - SC;
  if( lt > MAXEXP )
  goto overf;
  ac2[E] = lt;
  }
 }
done:
qmov( ac2, c );
return 0;

underf:
qclear(c);
return 0;

overf:
mtherr( "qadd", OVERFLOW );
qinfin(c);
return 0;
}

/*
; divide
;
; QELT a[NQ], b[NQ], c[NQ];
; qdiv( a, b, c ); c = b / a
*/

/* for Newton iteration version:
 * extern short qtwo[];
 * static short qt[NQ] = {0};
 * static short qu[NQ] = {0};
 */

int qdiv( a, b, c )
QELT *a, *b, *c;
{
long lt;

if( b[E] == 0 )
 {
divunderf:
 qclear(c); /* numerator is zero */
 return 0;
 }

if( a[E] == 0 )
 { /* divide by zero */
 qinfin(c);
 mtherr( "qdiv", SING );
 return 0;
 }
qmovz( b, ac3 );

/* Avoid exponent underflow in mdnorm.  */
lt = (long) ac3[E];
ac3[E] = 4;

divm( a, ac3 );
/* calculate exponent */
lt = lt + (long )ac3[E] -4L - (long )a[E];
ac3[E] = lt;
ac3[NQ] = 0;
normlz(ac3);
lt = lt - SC + EXPONE + 1;
if( lt > MAXEXP )
 {
 qinfin(ac3);
 mtherr( "qdiv", OVERFLOW );
 }
else if( lt <= 0 )
 goto divunderf; 
else
 ac3[E] = lt;

if( a[SIGNWORD] == b[SIGNWORD] )
 ac3[SIGNWORD] = 0;
else
 ac3[SIGNWORD] = -1;

qmov( ac3, c );
return 0;
}

/*
; multiply
;
; QELT a[NQ], b[NQ], c[NQ];
; qmul( a, b, c ); c = b * a
*/

int qmul( a, b, c )
QELT *a, *b, *c;
{
QELT *p;
register int ctr;
long lt;

if( (a[E] == 0) || (b[E] == 0) )
 {
 qclear(c);
 return 0;
 }
/* detect multiplication by small integer a */
if( a[M+2] == 0 )
 {
 p = &a[M+3];
 for( ctr=M+3; ctr<NQ; ctr++ )
  {
  if( *p++ != 0 )
   goto nota;
  }
 qmov( b, ac3 );
 mulin( a, ac3 );
 lt = ((long)a[E] - (EXPONE-1)) + ((long )ac3[E] - (EXPONE - 1));
 goto mulcon;
 }

nota:
/* detect multiplication by small integer b */
if( b[M+2] == 0 )
 {
 p = &b[M+3];
 for( ctr=M+3; ctr<NQ; ctr++ )
  {
  if( *p++ != 0 )
   goto notb;
  }
 qmov( a, ac3 );
 mulin( b, ac3 );
 lt = ((long)b[E] - (EXPONE-1)) + ((long )ac3[E] - (EXPONE - 1));
 goto mulcon;
 }

notb:

qmov( a, ac3 );
mulm( b, ac3 );
lt = ((long)b[E] - (EXPONE-1)) + ((long )ac3[E] - (EXPONE - 1));

mulcon:
/* calculate sign of product */
if( b[SIGNWORD] == a[SIGNWORD] )
 ac3[SIGNWORD] = 0;
else
 ac3[SIGNWORD] = -1;

if( lt > MAXEXP )
 goto overf;
ac3[E] = lt;
ac3[NQ] = 0;
if( normlz(ac3) )
 goto underf;
lt = lt - SC + EXPONE -1;
if( lt > MAXEXP )
 goto overf;
if( lt < 0 )
 goto underf;
ac3[E] = lt;
qmov( ac3, c );
return 0;

underf:
qclear(c);
return 0;

overf:
qinfin(c);
mtherr( "qmul", OVERFLOW );
return 0;
}




/* Multiply, a has at most WORDSIZE significant bits */

int qmuli( a, b, c )
QELT *a, *b, *c;
{
long lt;

if( (a[E] == 0) || (b[E] == 0) )
 {
 qclear(c);
 return 0;
 }

qmov( b, ac3 );
mulin( a, ac3 );

/* calculate sign of product */
if( b[SIGNWORD] == a[SIGNWORD] )
 ac3[SIGNWORD] = 0;
else
 ac3[SIGNWORD] = -1;

/* calculate exponent */
lt = ((long)ac3[E] - (EXPONE-1)) + ((long )a[E] - (EXPONE - 1));
if( lt > MAXEXP )
 goto overf;
ac3[E] = lt;
ac3[NQ] = 0;
if( normlz(ac3) )
 goto underf;
lt = lt - SC + EXPONE - 1;
if( lt > MAXEXP )
 goto overf;
if( lt < 0 )
 goto underf;
ac3[E] = lt;
qmov( ac3, c );
return 0;

underf:
qclear(c);
return 0;

overf:
qinfin(c);
mtherr( "qmuli", OVERFLOW );
return 0;
}




/*
; Compare mantissas
;
; QELT a[NQ], b[NQ];
; cmpm( a, b );
;
; for the mantissas:
; returns +1 if a > b
;   0 if a == b
;  -1 if a < b
*/


int cmpm( a, b )
register QELT *a, *b;
{
int i;

a += M; /* skip up to mantissa area */
b += M;
for( i=0; i<OMG; i++ )
 {
 if( *a++ != *b++ )
  goto difrnt;
 }
return(0);

difrnt:
if( (unsigned int) *(--a) > (unsigned int) *(--b) )
 return(1);
else
 return(-1);
}

/*
; shift mantissa
;
; Shifts mantissa area up or down by the number of bits
; given by the variable SC.
*/


int shift( x )
QELT *x;
{
QELT *p;
#if STICKY
int lost;
#endif

if( SC == 0 )
 return(0);

#if STICKY
lost = 0;
#endif
if( SC < 0 )
 {
 p = x + NQ;
 SC = -SC;
 while( SC >= 16 )
  {
#if STICKY
  lost |= *p;
#endif
  shdn16(x);
  SC -= 16;
  }

 while( SC >= 8 )
  {
#if STICKY
  lost |= *p & 0xff;
#endif
  shdn8(x);
  SC -= 8;
  }

 while( SC > 0 )
  {
#if STICKY
  lost |= *p & 1;
#endif
  shdn1(x);
  SC -= 1;
  }
 }
else
 {
 while( SC >= 16 )
  {
  shup16(x);
  SC -= 16;
  }

 while( SC >= 8 )
  {
  shup8(x);
  SC -= 8;
  }

 while( SC > 0 )
  {
  shup1(x);
  SC -= 1;
  }
 }
#if STICKY
return( lost );
#else
return(0);
#endif
}

/*
; normalize
;
; shift normalizes the mantissa area pointed to by R1
; shift count (up = positive) returned in SC
*/


int normlz(x)
QELT x[];
{
register QELT *p;

SC = 0;
p = &x[M];
if( *p != 0 )
 goto normdn;
++p;
if( *p & SIGNBIT )
 return(0); /* already normalized */

while( *p == 0 )
 {
 shup16(x);
 SC += 16;
/* With guard word, there are NBITS+WORDSIZE bits available.
 * return true if all are zero.
 */

 if( SC > NBITS )
  return(1);
 }

/* see if high byte is zero */
while( (*p & 0xff00) == 0 )
 {
 shup8(x);
 SC += 8;
 }

/* now shift 1 bit at a time */
while( (*p & SIGNBIT) == 0)
 {
 shup1(x);
 SC += 1;
/*
 if( SC > NBITS )
  {
  printf( "normlz error\n");
  return(0);
  }
*/

 }
return(0);

/* normalize by shifting down out of the high guard word
   of the mantissa */


normdn:

if( *p & 0xff00 )
 {
 shdn8(x);
 SC -= 8;
 }
while( *p != 0 )
 {
 shdn1(x);
 SC -= 1;
/*
 if( SC < -NBITS )
  {
  printf( "low normlz error\n");
  return(0);
  }
*/

 }
return(0);
}

/*
; Clear out entire number, including sign and exponent, pointed
; to by x
;
; QELT x[];
; qclear( x );
*/

/* Moved to qfltb.c */
#if 0
int qclear( x )
register QELT *x;
{
register int i;

for( i=0; i<NQ; i++ )
 *x++ = 0;
return 0;
}
#endif

/*
; Fill entire number, including exponent and mantissa, with
; largest possible number.
*/


int qinfin(x)
QELT *x;
{
register int i;

++x; /* skip over the sign */
*x++ = MAXEXP;
*x++ = 0;
for( i=0; i<OMG-1; i++ )
 *x++ = -1;
return 0;
}

/* normalization program */
int qnrmlz(x)
QELT *x;
{

qmovz( x, ac1 );
normlz( ac1 ); /* shift normalize the mantissa */
ac1[E] -= SC; /* subtract the shift count from the exponent */
qmov( ac1, x );
return 0;
}


/*
; Convert IEEE single precision to e type
; float d;
; unsigned short x[N+2];
; dtox( &d, x );
*/

int e24toq( pe, y )
unsigned short *pe;
QELT *y;
{
register unsigned short r;
register unsigned short *e;
QELT *p;
QELT yy[NQ+1];
int denorm;
unsigned long m;

e = pe;
denorm = 0; /* flag if denormalized number */
qclear(yy);
yy[NQ] = 0;
#ifdef IBMPC
e += 1;
#endif
#ifdef DEC
e += 1;
#endif
r = *e;
if( r & 0x8000 )
 yy[SIGNWORD] = -1;
yy[M] = (r & 0x7f) | 0200;
r &= ~0x807f; /* strip sign and 7 significand bits */
if( r == 0x7f80 )
 {
 qclear( y );
 qinfin( y );
 if( yy[SIGNWORD] )
  qneg(y);
 return 0;
 }
r >>= 7;
/* If zero exponent, then the significand is denormalized.
 * So take back the understood high significand bit. */
 
if( r == 0 )
 {
 denorm = 1;
 yy[M] &= ~0200;
 }
r += EXPONE - 0177;
yy[E] = r;
p = &yy[M+1];

#ifdef IBMPC
m = *(--e);
#endif
#ifdef DEC
m = *(--e);
#endif
#ifdef MIEEE
++e;
m = *e++;
#endif
#if WORDSIZE == 32
m <<= 16;
#endif
*p++ = m;
shdn8( yy );
if( denorm )
 { /* if zero exponent, then normalize the significand */
   normlz(yy);
 if( SC > NBITS )
  qclear(yy);
 else
  yy[E] -= (QELT) (SC-1);
 }
qmov( yy, y );
return 0;
}

/*
; e type to IEEE single precision
; float d;
; QELT x[NQ];
; xtod( x, &d );
*/

int qtoe24( x, e )
QELT *x;
unsigned short *e;
{
long exp;
QELT xi[NQ+1];
QELT *p;
QELT k;
unsigned long f;
int j, sign;

qmov( x, xi );
xi[NQ] = 0;
p = &xi[0];
f = 0L;
if( *p++ )
 sign = 0x8000; /* output sign bit */
else
 sign = 0;

exp = (long )*p++ - (EXPONE - 0177); /* adjust exponent for offsets */

if( exp <= 0 )
 {
 if( exp > -24 )
  {
  SC = exp - 1;
  shift( xi );
  exp = 0;
  }
 else
  {
  f = 0;
  goto fout;
  }
 }
/* round off to nearest or even */
#if WORDSIZE == 32
k = xi[M+1];
#else
k = xi[M+2];
#endif
if( (k & 0x80) != 0 )
 {
 if( (k & 0x0ff) == 0x80 )
  {
  if( (k & 0x100) != 0 )
   {
  /* check all less significant bits */
#if WORDSIZE == 32
   for( j=M+2; j<=NQ; j++ )
#else
   for( j=M+3; j<=NQ; j++ )
#endif
    {
    if( xi[j] != 0 )
     goto yesrnd;
    }
   }
  goto nornd;
  }
yesrnd:
 qclear( ac2 );
 ac2[NQ] = 0;
#if WORDSIZE == 32
 ac2[M+1] = 0x80;
#else
 ac2[M+2] = 0x80;
#endif
 addm( ac2, xi );
 if( xi[2] )
  {
  shdn1(xi);
  exp += 1;
  }
 if( (exp == 0) && (xi[M+1] & SIGNBIT) )
  exp += 1;
 }

nornd:

if( exp >= 255 )
 { /* Saturate at largest number less than infinity. */
#ifdef INFINITY
 f = (unsigned long )0x7f800000;
#else
 f = (unsigned long )0x7f7fffff;
#endif
 goto fout;
 }

f = *p++; /* Skip over high guard word.  */
f = *p++;
#if WORDSIZE == 16
f = (f << 16) | *p;
#endif

f &= 0x7fffffff;
/* f += 0x80; */  /* Retire old DEC rounding.  */
f >>= 8;
f |= (exp << 23) & 0x7f800000;
fout:
if(sign)
  f |= 0x80000000L;
#ifdef IBMPC
*e++ = f;
*e = f >> 16;
#endif
#ifdef DEC
*e++ = f;
*e = f >> 16;
#endif
#ifdef MIEEE
*e++ = f >> 16;
*e = f;
#endif
return 0;
}

/*
; Convert IEEE double precision to Q type
; double d;
; QELT q[NQ];
; etoq( &d, q );
*/


int etoq( e, y )
unsigned short *e;
QELT *y;
{
#ifdef DEC
dtoq(e,y);
#else
register int r;
register QELT *p;
QELT yy[NQ+1];
int denorm;


denorm = 0; /* flag if denormalized number */
qclear(yy);
yy[NQ] = 0;

#ifdef MIEEE

#endif

#ifdef IBMPC
e += M+1;
#endif

/*
r = *e & 0x7fff;
if( r == 0 )
 return 0;
*/


r = *e;
yy[SIGNWORD] = 0;
if( r & 0x8000 )
 yy[SIGNWORD] = -1;

yy[M] = (r & 0x0f) | 0x10;
r &= ~0x800f; /* strip sign and 4 mantissa bits */
r >>= 4;
/* If zero exponent, then the mantissa is denormalized.
 * So take back the understood high mantissa bit. */
 
if( r == 0 )
 {
 denorm = 1;
 yy[M] &= ~0x10;
 }
r += EXPONE - 01777;
yy[E] = r;
p = &yy[M+1];
#ifdef MIEEE
++e;
*p++ = *e++;
*p++ = *e++;
*p++ = *e++;
#endif
#ifdef IBMPC
*p++ = *(--e);
*p++ = *(--e);
*p++ = *(--e);
#endif
SC = -5;
shift(yy);
if( denorm )
 { /* if zero exponent, then normalize the mantissa */
 if( normlz( yy ) )
  qclear(yy);
 else
  yy[E] -= SC-1;
 }
qmov( yy, y );
/* not DEC */
#endif
return 0;
}

/*
; Q type to IEEE double precision
; double d;
; short q[NQ];
; qtoe( q, &d );
*/

int qtoe( x, e )
QELT *x;
unsigned short *e;
{
#ifdef DEC
qtod(x,e);
#else
int j, k;
long i;
register QELT *p;


#ifdef MIEEE

#endif
#ifdef IBMPC
e += M+1;
#endif


*e = 0; /* output high order */
p = &ac1[SIGNWORD];
qmovz( x, ac1 );
if( *p++ != 0 )
 *e = 0x8000; /* output sign bit */

if( normlz(ac1) )
 goto ozero;
*p -= SC;

i = (long) *p++ - (EXPONE - 1023); /* adjust exponent for offsets */

/* Handle denormalized small numbers.  */
if( i <= 0 )
 {
 if( i > -53 )
  {
  SC = i - 1;
  shift( ac1 );
  i = 0;
  }
 else
  {
ozero:
#ifdef MIEEE
  ++e;
  *e++ = 0;
  *e++ = 0;
  *e++ = 0;
#endif
#ifdef IBMPC
  *(--e) = 0;
  *(--e) = 0;
  *(--e) = 0;
#endif
  return 0;
  }
 }

/* round off to nearest or even */
k = ac1[M+4];
if( (k & 0x400) != 0 )
 {
 if( (k & 0x07ff) == 0x400 )
  {
  if( (k & 0x800) != 0 )
   {
  /* check all less significant bits */
   for( j=M+5; j<=NQ; j++ )
    {
    if( ac1[j] != 0 )
     goto yesrnd;
    }
   }
  goto nornd;
  }
yesrnd:
 qclear( ac2 );
 ac2[NQ] = 0;
 ac2[M+4] = 0x800;
 addm( ac2, ac1 );
 if( ac1[2] )
  {
  shdn1(ac1);
  i += 1;
  }
 if( (i == 0) && (ac1[3] & SIGNBIT) )
  i += 1;
 }

nornd:

if( i > 2047 )
 { /* Saturate at largest number less than infinity. */
 mtherr( "qtoe", OVERFLOW );
 *e |= 0x7fef;
#ifdef MIEEE
 ++e;
 *e++ = 0xffff;
 *e++ = 0xffff;
 *e++ = 0xffff;
#endif
#ifdef IBMPC
 *(--e) = 0xffff;
 *(--e) = 0xffff;
 *(--e) = 0xffff;
#endif
 return 0;
 }


i <<= 4;
SC = 5;
shift( ac1 );
i |= *p++ & 0x0f; /* *p = ac1[M] */
*e |= i; /* high order output already has sign bit set */
#ifdef MIEEE
++e;
*e++ = *p++;
*e++ = *p++;
*e++ = *p++;
#endif
#ifdef IBMPC
*(--e) = *p++;
*(--e) = *p++;
*(--e) = *p;
#endif
/* not DEC */
#endif
return 0;
}


/*
; Convert 80-bit IEEE long double precision to Q type
; long double d;
; QELT q[N+2];
; etoq( &d, q );
*/


int e64toq( e, y )
unsigned short *e;
QELT *y;
{
register int r;
register QELT *p;
QELT yy[NQ+1];
int denorm;


denorm = 0; /* flag if denormalized number */
qclear(yy);
yy[NQ] = 0;

#ifdef MIEEE

#endif


#ifdef IBMPC
e += 4;
#endif

r = *e;
yy[SIGNWORD] = 0;
if( r & 0x8000 )
 yy[SIGNWORD] = -1;

r &= 0x7fff;
/* If zero exponent, then the mantissa is denormalized. */
if( r == 0 )
 {
 denorm = 1;
 }
r += (EXPONE-0x3fff);
yy[E] = r;
p = &yy[M+1];
#if WORDSIZE== 32
#ifdef MIEEE
++e;
*p = ((unsigned int) *e++) << 16;
*p++ |= *e++;
*p = ((unsigned int) *e++) << 16;
*p++ |= *e++;
#endif
#ifdef IBMPC
*p = ((unsigned int) *(--e)) << 16;
*p++ |= *(--e);
*p = ((unsigned int) *(--e)) << 16;
*p++ |= *(--e);
#endif
#else
/* 16-bit wordsize */
#ifdef MIEEE
++e;
*p++ = *e++;
*p++ = *e++;
*p++ = *e++;
*p++ = *e++;
#endif
#ifdef IBMPC
*p++ = *(--e);
*p++ = *(--e);
*p++ = *(--e);
*p++ = *(--e);
#endif
#endif
if( denorm )
 { /* if zero exponent, then normalize the mantissa */
#ifdef IBMPC
/* For Intel long double, shift denormal significand up 1
   -- but only if the top significand bit is zero.  */

 if( (yy[M+1] & SIGNBIT) == 0 )
  shup1( yy );
#endif
 if( normlz( yy ) )
  qclear(yy);
 else
  yy[E] -= SC;
 }
qmov( yy, y );
return 0;
}

/*
; Q type to 80-bit IEEE long double precision
; long double d;
; QELT q[N+2];
; qtoe( q, &d );
*/

int qtoe64( x, e )
QELT *x;
unsigned short *e;
{
QELT k;
int j;
long i;
register QELT *p;


#ifdef MIEEE

#endif
#ifdef IBMPC
e += 4;
#if 0
/* NOTE: if data type is 96 bits wide, clear the last word here. */
*(e+1)= 0;
#endif
#endif


*e = 0; /* output high order */
p = &ac1[0];
qmovz( x, p );
if( ac1[SIGNWORD] )
 *e = 0x8000; /* output sign bit */
++p;
if( normlz(ac1) )
 goto o64zero;
*p -= SC;

i = (long) *p++ - (EXPONE-0x3fff); /* adjust exponent for offsets */
if( i >= 0x7fff)
 {
#ifdef MIEEE
 *e++ |= 0x7ffe;
 *e++ = 0xffff;
 *e++ = 0xffff;
 *e++ = 0xffff;
 *e++ = 0xffff;
#endif
#ifdef IBMPC
 *e-- |= 0x7ffe;
 *e-- = 0xffff;
 *e-- = 0xffff;
 *e-- = 0xffff;
 *e-- = 0xffff;
#endif
 return 0;
 }
/* We can't handle denormal numbers if the q-type exponenent is 0. */
if( i <= 0 )
 {
 if( i > -65 )
  {
#if BIGENDIAN
  SC = i;
#else
  /* Intel 80x87 loses a bit.  */
  SC = i - 1;
#endif
  shift( ac1 );
  i = 0;
  }
 else
  {
o64zero:
#ifdef MIEEE
  ++e;
  *e++ = 0;
  *e++ = 0;
  *e++ = 0;
  *e++ = 0;
#endif
#ifdef IBMPC
  *(--e) = 0;
  *(--e) = 0;
  *(--e) = 0;
  *(--e) = 0;
#endif
  return 0;
  }
 }

/* round off to nearest or even */
#if WORDSIZE == 32
k = ac1[M+3];
#else
k = ac1[M+5];
#endif
if( (k & SIGNBIT) != 0 )
 {
 if( (k & ((QELT) SIGNBIT - 1)) == 0 )
  {
  /* check all less significant bits */
#if WORDSIZE == 32
/* 0 1 2  3   4   5   6 */
/* S E M 1,2 3,4 5,6 7,8 */
  for( j=M+4; j<=NQ; j++ )
#else
/* 0 1 2 3 4 5 6 7 8 9 10 */
/* S E M 1 2 3 4 5 6 7 8 */
  for( j=M+6; j<=NQ; j++ )
#endif
   {
   if( ac1[j] != 0 )
    goto yesrnd;
   }
/* round to even */
#if WORDSIZE == 32
  if( (ac1[4] & 1) == 0 )
#else
  if( (ac1[6] & 1) == 0 )
#endif
    goto nornd;
  }
yesrnd:
 qclear( ac2 );
 ac2[NQ] = 0;
#if WORDSIZE == 32
 ac2[M+3] = SIGNBIT;
#else
 ac2[M+5] = SIGNBIT;
#endif
 addm( ac2, ac1 );
 if( ac1[M] )
  {
  shdn1(ac1);
  i += 1;
  }
 if( (i == 0) && (ac1[3] & SIGNBIT) )
  i += 1;
 }

nornd:

*e |= i; /* high order output already has sign bit set */
p = &ac1[M+1];
#if WORDSIZE == 32
#ifdef MIEEE
++e;
*e++ = *p >> 16;
*e++ = *p++;
*e++ = *p >> 16;
*e++ = *p++;
#endif
#ifdef IBMPC
*(--e) = *p >> 16;
*(--e) = *p++;
*(--e) = *p >> 16;
*(--e) = *p++;
#endif
#else
/* 16-bit words */
#ifdef MIEEE
++e;
*e++ = *p++;
*e++ = *p++;
*e++ = *p++;
*e++ = *p;
#endif
#ifdef IBMPC
*(--e) = *p++;
*(--e) = *p++;
*(--e) = *p++;
*(--e) = *p;
#endif
#endif
return 0;
}

/*
; Convert 128-bit IEEE long double precision to Q type
; long double d;
; QELT q[NQ];
; e113toq( &d, q );
*/


int e113toq( e, y )
unsigned short *e;
QELT *y;
{
register short r;
register QELT *p;
short yy[NQ+1];
int denorm;


denorm = 0; /* flag if denormalized number */
qclear(yy);
yy[NQ] = 0;

#ifdef MIEEE

#endif


#ifdef IBMPC
e += 7;
#endif

r = *e;
yy[0] = 0;
if( r & 0x8000 )
 yy[0] = -1;

r &= 0x7fff;
yy[M] = 1;
/* If zero exponent, then the mantissa is denormalized.
 * So, take back the understood high mantissa bit. */
 
if( r == 0 )
 {
 denorm = 1;
 yy[M] = 0;
 }
r += (EXPONE-0x3fff);
yy[E] = r;
p = &yy[M+1];
#ifdef MIEEE
++e;
*p++ = *e++;
*p++ = *e++;
*p++ = *e++;
*p++ = *e++;
*p++ = *e++;
*p++ = *e++;
*p++ = *e++;
#endif
#ifdef IBMPC
*p++ = *(--e);
*p++ = *(--e);
*p++ = *(--e);
*p++ = *(--e);
*p++ = *(--e);
*p++ = *(--e);
*p++ = *(--e);
#endif
SC = -1;
shift(yy);
if( denorm )
 { /* if zero exponent, then normalize the mantissa */
 if( normlz( yy ) )
  qclear(yy);
 else
  yy[E] -= SC-1;
 }
qmov( yy, y );
return 0;
}

/*
; Q type to 128-bit IEEE long double precision
; long double d;
; QELT q[NQ];
; qtoe113( q, &d );
*/

int qtoe113( x, e )
QELT *x;
unsigned short *e;
{
QELT k;
short i, j;
register QELT *p;


#ifdef MIEEE

#endif
#ifdef IBMPC
e += 7;
#endif


*e = 0; /* output high order */
p = &ac1[0];
qmovz( x, p );
if( *p++ != 0 )
 *e = 0x8000; /* output sign bit */

normlz(ac1);
*p -= SC;

if ((unsigned int) *p > (unsigned int) 0xc000)
  {
#ifdef MIEEE
 *e++ |= 0x7ffe;
 *e++ = 0xffff;

 *e++ = 0xffff;
 *e++ = 0xffff;

 *e++ = 0xffff;
 *e++ = 0xffff;

 *e++ = 0xffff;
 *e++ = 0xffff;
#endif
#ifdef IBMPC
 *e-- |= 0x7ffe;
 *e-- = 0xffff;

 *e-- = 0xffff;
 *e-- = 0xffff;

 *e-- = 0xffff;
 *e-- = 0xffff;

 *e-- = 0xffff;
 *e-- = 0xffff;
#endif
 return 0;
  }

i = *p++ - (EXPONE-0x3fff); /* adjust exponent for offsets */

/* We can't handle denormal numbers. */
if( i <= 0 )
 {
 if( i > -2 )
  {
  SC = i - 1;
  shift( ac1 );
  i = 0;
  }
 else
  {
/*ozero:*/
#ifdef MIEEE
  ++e;
  *e++ = 0;
  *e++ = 0;
  *e++ = 0;
  *e++ = 0;
  *e++ = 0;
  *e++ = 0;
  *e++ = 0;
#endif
#ifdef IBMPC
  *(--e) = 0;
  *(--e) = 0;
  *(--e) = 0;
  *(--e) = 0;
  *(--e) = 0;
  *(--e) = 0;
  *(--e) = 0;
#endif
  return 0;
  }
 }

/* round off to nearest or even */
/* 0 1 2 3 4 5 6 7 8 9 10 */
/* S E M 1 2 3 4 5 6 7 8 */
k = ac1[M+8];
if( (k & 0x4000) != 0 )
 {
 if( (k & 0x7fff) == 0x4000 )
  {
  /* check all less significant bits */
  for( j=M+9; j<=NQ; j++ )
   {
   if( ac1[j] != 0 )
    goto yesrnd;
   }
/* round to even */
  if( (k & 0x8000) == 0 )
    goto nornd;
  }
yesrnd:
 qclear( ac2 );
 ac2[NQ] = 0;
 ac2[M+8] = 0x8000;
 addm( ac2, ac1 );
 if( ac1[2] )
  {
  shdn1(ac1);
  i += 1;
  }
 if( (i == 0) && (ac1[3] & 0x8000) )
  i += 1;
 }

nornd:

SC = 1;
shift( ac1 );
*e |= i; /* high order output already has sign bit set */
p = &ac1[M+1];
#ifdef MIEEE
++e;
*e++ = *p++;
*e++ = *p++;
*e++ = *p++;
*e++ = *p++;
*e++ = *p++;
*e++ = *p++;
*e++ = *p++;
#endif
#ifdef IBMPC
*(--e) = *p++;
*(--e) = *p++;
*(--e) = *p++;
*(--e) = *p++;
*(--e) = *p++;
*(--e) = *p++;
*(--e) = *p;
#endif
return 0;
}




/* qtoasc.c */
/* Convert q type number to ASCII string */

/* Get values for powers of ten.  */
#include "qtens.h"

int qtoasc( q, string, ndigs )
QELT q[];
char *string;
int ndigs;
{
long digit;
QELT x[NTT], xt[NTT];
QELT *p, *r, *ten, *tenth;
QELT sign;
int i, k, expon;
char *s, *ss;

qmov( q, x );
sign = x[SIGNWORD];
x[SIGNWORD] = 0;
expon = 0;
ten = &qtens[NTEN][0];

i = qcmp( qone, x );
if( i == 0 )
 goto isone;
if( x[1] == 0 )
 {
 qclear( x );
 goto isone;
 }

if( i < 0 )
 {
 k = MAXNTEN;
 p = &qtens[0][0];
 qmov( qone, ac4 );
 qmov( x, xt );
 while( qcmp( ten, x ) <= 0 )
  {
  if( qcmp( p, xt ) <= 0 )
   {
   qdiv( p, xt, xt );
   qmul( p, ac4, ac4 );
   expon += k;
   }
  k >>= 1;
  if( k == 0 )
   break;
  p += NTT;
  }
 qdiv( ac4, x, x );
 }
else
 {
 k = MINNTEN;
 p = &qmtens[0][0];
 r = &qtens[0][0];
 tenth = &qmtens[NTEN][0];
 while( qcmp( tenth, x ) > 0 )
  {
  if( qcmp( p, x ) >= 0 )
   {
   qmul( r, x, x );
   expon += k;
   }
  k /= 2;
/* Prevent infinite loop due to arithmetic error: */
  if( k == 0 )
   break;
  p += NTT;
  r += NTT;
  }
 qmuli( ten, x, x );
 expon -= 1;
 }

isone:
qifrac( x, &digit, x );
/* The following check handles numbers very close to 10**(2**n)
 * when there is a mistake due to arithmetic error.
 */

if( digit >= 10 )
 {
 qdiv( ten, x, x );
 expon += 1;
 digit = 1;
 }
s = string;
if( sign != 0 )
 *s++ = '-';
else
 *s++ = ' ';
*s++ = (char )digit + 060;
*s++ = '.';
if( ndigs < 0 )
 ndigs = 0;
if( ndigs > NDEC )
 ndigs = NDEC;
for( k=0; k<ndigs; k++ )
 {
 qmuli( ten, x, x );
 qifrac( x, &digit, x );
 *s++ = (char )digit + 060;
 }

*s = '\0'; /* mark end of string */
ss = s;

/* round off the ASCII string */

qmuli( ten, x, x );
qifrac( x, &digit, x );
if( digit > 4 )
 {
/* Check for critical rounding case */
 if( digit == 5 )
  {
  if( qcmp( x, qzero ) != 0 )
   goto roun; /* round to nearest */
  if( (*(s-1) & 1) == 0 )
   goto doexp; /* round to even */
  }
roun:
 --s;
 k = *s & 0x7f;
/* Carry out to most significant digit? */
 if( k == '.' )
  {
  --s;
  k = *s & 0x7f;
  k += 1;
  *s = k;
/* Most significant digit rounds to 10? */
  if( k > '9' )
   {
   *s = '1';
   expon += 1;
   }
  goto doexp;
  }
/* Round up and carry out from less significant digits. */
 k += 1;
 *s = k;
 if( k > '9' )
  {
  *s = '0';
  goto roun;
  }
 }

doexp:

sprintf( ss, "E%d", expon );
return 0;
}


/* QELT a[NQ], b[NQ];
 * qcmp( a, b )
 *
 *  returns +1 if a > b
 *           0 if a == b
 *          -1 if a < b
 */


int qcmp( p, q )
register QELT *p, *q;
{
QELT r[NQ];
register int i;
int msign;

if( ( *(p+1) <= (QELT)NBITS)  && ( *(q+1) <= (QELT)NBITS ) )
 {
 qsub( q, p, r );
 if( r[E] == 0 )
  return( 0 );
 if( r[SIGNWORD] == 0 )
  return( 1 );
 return( -1 );
 }

if( *p != *q )
 { /* the signs are different */
 if( p[SIGNWORD] == 0 )
  return( 1 );
 else
  return( -1 );
 }

/* both are the same sign */
if( *p == 0 )
 msign = 1;
else
 msign = -1;
 
i = NQ;
do
 {
 if( *p++ != *q++ )
  {
  goto diff;
  }
 }
while( --i > 0 );

return(0); /* equality */



diff:

if( (unsigned int) *(--p) > (unsigned int) *(--q) )
 return( msign );  /* p is bigger */
else
 return( -msign ); /* p is littler */
}



/*
;        ASCTOQ
;  ASCTOQ.MAC  LATEST REV: 11 JAN 84
;     SLM, 3 JAN 78
;
; Convert ASCII string to quadruple precision floating point
;
;  Numeric input is free field decimal number
;  with max of 15 digits with or without 
;  decimal point entered as ASCII from teletype.
; Entering E after the number followed by a second
; number causes the second number to be interpreted
; as a power of 10 to be multiplied by the first number
; (i.e., "scientific" notation).
;
; Usage:
;  asctoq( string, q );
*/


int asctoq( s, y )
char *s;
QELT *y;
{
QELT yy[NQ+1], qt[NQ];
int esign, nsign, decflg, sgnflg, nexp, exp, prec;
QELT *p;


nsign = 0;
esign = 1;
decflg = 0;
sgnflg = 0;
nexp = 0;
exp = 0;
prec = 0;
qclear( yy );
yy[NQ] = 0;

nxtcom:
if( (*s >= '0') && (*s <= '9') )
{
if( (prec == 0) && (decflg == 0) && (*s == '0') )
 goto donchr;
if( prec < NDEC )
 {
 if( decflg )
  nexp += 1; /* count digits after decimal point */
 shup1( yy ); /* multiply current number by 10 */
 qmovz( yy, ac2 );
 shup1( ac2 );
 shup1( ac2 );
 addm( ac2, yy );
 qclear( ac2 );
 ac2[OMG+1] = *s - '0';
 addm( ac2, yy );
 }
prec += 1;
goto donchr;
}

switch( *s )
{
case ' ':
 break;
case 'E':
case 'e':
 goto expnt;
case '.': /* decimal point */
 if( decflg )
  goto error;
 ++decflg;
 break;
case '-':
 nsign = -1;
case '+':
 if( sgnflg )
  goto error;
 ++sgnflg;
 break;
case '\0':
/* For Microware OS-9 operating system: */
#ifndef OSK
case '\n':
#endif
case '\r':
 goto daldone;
default:
error:
 printf( "asctoq conversion error\n" );
 qclear(y);
 return 0;
}
donchr:
++s;
goto nxtcom;


/* EXPONENT INTERPRETATION */
expnt:

/* 0.0eXXX is zero, regardless of XXX.  Check for the 0.0. */
for( exp = 0; exp < NQ + 1; exp++ )
 {
 if( yy[exp] != 0 )
  goto read_expnt;
 }
goto zero;
  
read_expnt:
exp = 0;
++s;
/* check for + or - */
if( *s == '-' )
 {
 esign = -1;
 ++s;
 }
if( *s == '+' )
 ++s;
while( (*s >= '0') && (*s <= '9') )
 {
 /* Check for oversize decimal exponent.  */
 if( exp >= 3276 || exp < 0 )
  {
  if( esign < 0 )
   goto zero;
  else
   goto infinite;
  }
 exp *= 10;
 exp += *s++ - '0';
 }
if( esign < 0 )
 exp = -exp;

daldone:
nexp = exp - nexp;

if( normlz(yy) )
 {
 qclear(y);
 return 0;
 }

yy[E] = EXPONE - 1 + NBITS - SC;
qmov( yy, y );
y[SIGNWORD] = nsign;

/* Escape from excessively large exponent.  */
if( nexp >= 2 * MAXNTEN )
 {
infinite:
 y[SIGNWORD] = nsign;
 qinfin(y);
 mtherr( "asctoq", OVERFLOW );
 goto aexit;
 }
if( nexp <= -2 * MAXNTEN )
 {
zero:
 qclear(y);
 mtherr( "asctoq", UNDERFLOW );
 goto aexit;
 }

/* multiply or divide by 10**NEXP */
if( nexp == 0 )
 goto aexit;
esign = 0;
if( nexp < 0 )
 {
 esign = -1;
 nexp = -nexp;
 }

p = &qtens[NTEN][0];
exp = 1;
qmov( qone, qt );

do
 {
 if( exp & nexp )
  qmul( p, qt, qt );
 exp <<= 1;
 p -= NQ;
 }
while( exp <= MAXNTEN );

if( esign < 0 )
 qdiv( qt, y, y );
else
 qmul( qt, y, y );
aexit:
return 0;
}


Messung V0.5 in Prozent
C=85 H=93 G=88

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.35Angebot  ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Bemerkung:

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Anfrage:

Dauer der Verarbeitung:

Sekunden

sprechenden Kalenders