Esempio n. 1
0
/* ------------------------------------------------------------------ */
decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
			      decContext *set) {
  uInt status=0;		   /* status accumulator */
  Int ae;			   /* adjusted exponent */
  decNumber  dw;		   /* work */
  decContext dc;		   /* .. */
  uInt comb, exp;		   /* .. */
  uInt uiwork;			   /* for macros */
  uInt targ=0;			   /* target 32-bit */

  /* If the number has too many digits, or the exponent could be */
  /* out of range then reduce the number under the appropriate */
  /* constraints.  This could push the number to Infinity or zero, */
  /* so this check and rounding must be done before generating the */
  /* decimal32] */
  ae=dn->exponent+dn->digits-1; 	     /* [0 if special] */
  if (dn->digits>DECIMAL32_Pmax 	     /* too many digits */
   || ae>DECIMAL32_Emax 		     /* likely overflow */
   || ae<DECIMAL32_Emin) {		     /* likely underflow */
    decContextDefault(&dc, DEC_INIT_DECIMAL32); /* [no traps] */
    dc.round=set->round;		     /* use supplied rounding */
    decNumberPlus(&dw, dn, &dc);	     /* (round and check) */
    /* [this changes -0 to 0, so enforce the sign...] */
    dw.bits|=dn->bits&DECNEG;
    status=dc.status;			     /* save status */
    dn=&dw;				     /* use the work number */
    } /* maybe out of range */

  if (dn->bits&DECSPECIAL) {			  /* a special value */
    if (dn->bits&DECINF) targ=DECIMAL_Inf<<24;
     else {					  /* sNaN or qNaN */
      if ((*dn->lsu!=0 || dn->digits>1) 	  /* non-zero coefficient */
       && (dn->digits<DECIMAL32_Pmax)) {	  /* coefficient fits */
	decDigitsToDPD(dn, &targ, 0);
	}
      if (dn->bits&DECNAN) targ|=DECIMAL_NaN<<24;
       else targ|=DECIMAL_sNaN<<24;
      } /* a NaN */
    } /* special */

   else { /* is finite */
    if (decNumberIsZero(dn)) {		     /* is a zero */
      /* set and clamp exponent */
      if (dn->exponent<-DECIMAL32_Bias) {
	exp=0;				     /* low clamp */
	status|=DEC_Clamped;
	}
       else {
	exp=dn->exponent+DECIMAL32_Bias;     /* bias exponent */
	if (exp>DECIMAL32_Ehigh) {	     /* top clamp */
	  exp=DECIMAL32_Ehigh;
	  status|=DEC_Clamped;
	  }
	}
      comb=(exp>>3) & 0x18;		/* msd=0, exp top 2 bits .. */
      }
     else {				/* non-zero finite number */
      uInt msd; 			/* work */
      Int pad=0;			/* coefficient pad digits */

      /* the dn is known to fit, but it may need to be padded */
      exp=(uInt)(dn->exponent+DECIMAL32_Bias);	  /* bias exponent */
      if (exp>DECIMAL32_Ehigh) {		  /* fold-down case */
	pad=exp-DECIMAL32_Ehigh;
	exp=DECIMAL32_Ehigh;			  /* [to maximum] */
	status|=DEC_Clamped;
	}

      /* fastpath common case */
      if (DECDPUN==3 && pad==0) {
	targ=BIN2DPD[dn->lsu[0]];
	if (dn->digits>3) targ|=(uInt)(BIN2DPD[dn->lsu[1]])<<10;
	msd=(dn->digits==7 ? dn->lsu[2] : 0);
	}
       else { /* general case */
	decDigitsToDPD(dn, &targ, pad);
	/* save and clear the top digit */
	msd=targ>>20;
	targ&=0x000fffff;
	}

      /* create the combination field */
      if (msd>=8) comb=0x18 | ((exp>>5) & 0x06) | (msd & 0x01);
	     else comb=((exp>>3) & 0x18) | msd;
      }
Esempio n. 2
0
/* ------------------------------------------------------------------ */
decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
				decContext *set) {
  uInt status=0;		   /* status accumulator */
  Int ae;			   /* adjusted exponent */
  decNumber  dw;		   /* work */
  decContext dc;		   /* .. */
  uInt *pu;			   /* .. */
  uInt comb, exp;		   /* .. */
  uInt targar[2]={0, 0};	   /* target 64-bit */
  #define targhi targar[1]	   /* name the word with the sign */
  #define targlo targar[0]	   /* and the other */

  /* If the number has too many digits, or the exponent could be */
  /* out of range then reduce the number under the appropriate */
  /* constraints.  This could push the number to Infinity or zero, */
  /* so this check and rounding must be done before generating the */
  /* decimal64] */
  ae=dn->exponent+dn->digits-1;		     /* [0 if special] */
  if (dn->digits>DECIMAL64_Pmax		     /* too many digits */
   || ae>DECIMAL64_Emax			     /* likely overflow */
   || ae<DECIMAL64_Emin) {		     /* likely underflow */
    decContextDefault(&dc, DEC_INIT_DECIMAL64); /* [no traps] */
    dc.round=set->round;		     /* use supplied rounding */
    decNumberPlus(&dw, dn, &dc);	     /* (round and check) */
    /* [this changes -0 to 0, so enforce the sign...] */
    dw.bits|=dn->bits&DECNEG;
    status=dc.status;			     /* save status */
    dn=&dw;				     /* use the work number */
    } /* maybe out of range */

  if (dn->bits&DECSPECIAL) {			  /* a special value */
    if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
     else {					  /* sNaN or qNaN */
      if ((*dn->lsu!=0 || dn->digits>1)		  /* non-zero coefficient */
       && (dn->digits<DECIMAL64_Pmax)) {	  /* coefficient fits */
	decDigitsToDPD(dn, targar, 0);
	}
      if (dn->bits&DECNAN) targhi|=DECIMAL_NaN<<24;
       else targhi|=DECIMAL_sNaN<<24;
      } /* a NaN */
    } /* special */

   else { /* is finite */
    if (decNumberIsZero(dn)) {		     /* is a zero */
      /* set and clamp exponent */
      if (dn->exponent<-DECIMAL64_Bias) {
	exp=0;				     /* low clamp */
	status|=DEC_Clamped;
	}
       else {
	exp=dn->exponent+DECIMAL64_Bias;     /* bias exponent */
	if (exp>DECIMAL64_Ehigh) {	     /* top clamp */
	  exp=DECIMAL64_Ehigh;
	  status|=DEC_Clamped;
	  }
	}
      comb=(exp>>5) & 0x18;		/* msd=0, exp top 2 bits .. */
      }
     else {				/* non-zero finite number */
      uInt msd;				/* work */
      Int pad=0;			/* coefficient pad digits */

      /* the dn is known to fit, but it may need to be padded */
      exp=(uInt)(dn->exponent+DECIMAL64_Bias);	  /* bias exponent */
      if (exp>DECIMAL64_Ehigh) {		  /* fold-down case */
	pad=exp-DECIMAL64_Ehigh;
	exp=DECIMAL64_Ehigh;			  /* [to maximum] */
	status|=DEC_Clamped;
	}

      /* fastpath common case */
      if (DECDPUN==3 && pad==0) {
	uInt dpd[6]={0,0,0,0,0,0};
	uInt i;
	Int d=dn->digits;
	for (i=0; d>0; i++, d-=3) dpd[i]=BIN2DPD[dn->lsu[i]];
	targlo =dpd[0];
	targlo|=dpd[1]<<10;
	targlo|=dpd[2]<<20;
	if (dn->digits>6) {
	  targlo|=dpd[3]<<30;
	  targhi =dpd[3]>>2;
	  targhi|=dpd[4]<<8;
	  }
	msd=dpd[5];		   /* [did not really need conversion] */
	}
Esempio n. 3
0
/* ------------------------------------------------------------------ */
decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
				  decContext *set) {
  uInt status=0;		   /* status accumulator */
  Int ae;			   /* adjusted exponent */
  decNumber  dw;		   /* work */
  decContext dc;		   /* .. */
  uInt comb, exp;		   /* .. */
  uInt uiwork;			   /* for macros */
  uInt targar[4]={0,0,0,0};	   /* target 128-bit */
  #define targhi targar[3]	   /* name the word with the sign */
  #define targmh targar[2]	   /* name the words */
  #define targml targar[1]	   /* .. */
  #define targlo targar[0]	   /* .. */

  /* If the number has too many digits, or the exponent could be */
  /* out of range then reduce the number under the appropriate */
  /* constraints.  This could push the number to Infinity or zero, */
  /* so this check and rounding must be done before generating the */
  /* decimal128] */
  ae=dn->exponent+dn->digits-1; 	     /* [0 if special] */
  if (dn->digits>DECIMAL128_Pmax	     /* too many digits */
   || ae>DECIMAL128_Emax		     /* likely overflow */
   || ae<DECIMAL128_Emin) {		     /* likely underflow */
    decContextDefault(&dc, DEC_INIT_DECIMAL128); /* [no traps] */
    dc.round=set->round;		     /* use supplied rounding */
    decNumberPlus(&dw, dn, &dc);	     /* (round and check) */
    /* [this changes -0 to 0, so enforce the sign...] */
    dw.bits|=dn->bits&DECNEG;
    status=dc.status;			     /* save status */
    dn=&dw;				     /* use the work number */
    } /* maybe out of range */

  if (dn->bits&DECSPECIAL) {			  /* a special value */
    if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
     else {					  /* sNaN or qNaN */
      if ((*dn->lsu!=0 || dn->digits>1) 	  /* non-zero coefficient */
       && (dn->digits<DECIMAL128_Pmax)) {	  /* coefficient fits */
	decDigitsToDPD(dn, targar, 0);
	}
      if (dn->bits&DECNAN) targhi|=DECIMAL_NaN<<24;
       else targhi|=DECIMAL_sNaN<<24;
      } /* a NaN */
    } /* special */

   else { /* is finite */
    if (decNumberIsZero(dn)) {		     /* is a zero */
      /* set and clamp exponent */
      if (dn->exponent<-DECIMAL128_Bias) {
	exp=0;				     /* low clamp */
	status|=DEC_Clamped;
	}
       else {
	exp=dn->exponent+DECIMAL128_Bias;    /* bias exponent */
	if (exp>DECIMAL128_Ehigh) {	     /* top clamp */
	  exp=DECIMAL128_Ehigh;
	  status|=DEC_Clamped;
	  }
	}
      comb=(exp>>9) & 0x18;		/* msd=0, exp top 2 bits .. */
      }
     else {				/* non-zero finite number */
      uInt msd; 			/* work */
      Int pad=0;			/* coefficient pad digits */

      /* the dn is known to fit, but it may need to be padded */
      exp=(uInt)(dn->exponent+DECIMAL128_Bias);    /* bias exponent */
      if (exp>DECIMAL128_Ehigh) {		   /* fold-down case */
	pad=exp-DECIMAL128_Ehigh;
	exp=DECIMAL128_Ehigh;			   /* [to maximum] */
	status|=DEC_Clamped;
	}

      /* [fastpath for common case is not a win, here] */
      decDigitsToDPD(dn, targar, pad);
      /* save and clear the top digit */
      msd=targhi>>14;
      targhi&=0x00003fff;

      /* create the combination field */
      if (msd>=8) comb=0x18 | ((exp>>11) & 0x06) | (msd & 0x01);
	     else comb=((exp>>9) & 0x18) | msd;
      }
Esempio n. 4
0
/* ------------------------------------------------------------------ */
decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
                                decContext *set) {
  uInt status=0;                   // status accumulator
  Int ae;                          // adjusted exponent
  decNumber  dw;                   // work
  decContext dc;                   // ..
  uInt comb, exp;                  // ..
  uInt uiwork;                     // for macros
  uInt targar[2]={0, 0};           // target 64-bit
  #define targhi targar[1]         // name the word with the sign
  #define targlo targar[0]         // and the other

  // If the number has too many digits, or the exponent could be
  // out of range then reduce the number under the appropriate
  // constraints.  This could push the number to Infinity or zero,
  // so this check and rounding must be done before generating the
  // decimal64]
  ae=dn->exponent+dn->digits-1;              // [0 if special]
  if (dn->digits>DECIMAL64_Pmax              // too many digits
   || ae>DECIMAL64_Emax                      // likely overflow
   || ae<DECIMAL64_Emin) {                   // likely underflow
    decContextDefault(&dc, DEC_INIT_DECIMAL64); // [no traps]
    dc.round=set->round;                     // use supplied rounding
    decNumberPlus(&dw, dn, &dc);             // (round and check)
    // [this changes -0 to 0, so enforce the sign...]
    dw.bits|=dn->bits&DECNEG;
    status=dc.status;                        // save status
    dn=&dw;                                  // use the work number
    } // maybe out of range

  if (dn->bits&DECSPECIAL) {                      // a special value
    if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
     else {                                       // sNaN or qNaN
      if ((*dn->lsu!=0 || dn->digits>1)           // non-zero coefficient
       && (dn->digits<DECIMAL64_Pmax)) {          // coefficient fits
        decDigitsToDPD(dn, targar, 0);
        }
      if (dn->bits&DECNAN) targhi|=DECIMAL_NaN<<24;
       else targhi|=DECIMAL_sNaN<<24;
      } // a NaN
    } // special

   else { // is finite
    if (decNumberIsZero(dn)) {               // is a zero
      // set and clamp exponent
      if (dn->exponent<-DECIMAL64_Bias) {
        exp=0;                               // low clamp
        status|=DEC_Clamped;
        }
       else {
        exp=dn->exponent+DECIMAL64_Bias;     // bias exponent
        if (exp>DECIMAL64_Ehigh) {           // top clamp
          exp=DECIMAL64_Ehigh;
          status|=DEC_Clamped;
          }
        }
      comb=(exp>>5) & 0x18;             // msd=0, exp top 2 bits ..
      }
     else {                             // non-zero finite number
      uInt msd;                         // work
      Int pad=0;                        // coefficient pad digits

      // the dn is known to fit, but it may need to be padded
      exp=(uInt)(dn->exponent+DECIMAL64_Bias);    // bias exponent
      if (exp>DECIMAL64_Ehigh) {                  // fold-down case
        pad=exp-DECIMAL64_Ehigh;
        exp=DECIMAL64_Ehigh;                      // [to maximum]
        status|=DEC_Clamped;
        }

      // fastpath common case
      if (DECDPUN==3 && pad==0) {
        uInt dpd[6]={0,0,0,0,0,0};
        uInt i;
        Int d=dn->digits;
        for (i=0; d>0; i++, d-=3) dpd[i]=BIN2DPD[dn->lsu[i]];
        targlo =dpd[0];
        targlo|=dpd[1]<<10;
        targlo|=dpd[2]<<20;
        if (dn->digits>6) {
          targlo|=dpd[3]<<30;
          targhi =dpd[3]>>2;
          targhi|=dpd[4]<<8;
          }
        msd=dpd[5];                // [did not really need conversion]
        }
Esempio n. 5
0
/* ------------------------------------------------------------------ */
decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
                              decContext *set) {
  uInt status=0;                   // status accumulator
  Int ae;                          // adjusted exponent
  decNumber  dw;                   // work
  decContext dc;                   // ..
  uInt comb, exp;                  // ..
  uInt uiwork;                     // for macros
  uInt targ=0;                     // target 32-bit

  // If the number has too many digits, or the exponent could be
  // out of range then reduce the number under the appropriate
  // constraints.  This could push the number to Infinity or zero,
  // so this check and rounding must be done before generating the
  // decimal32]
  ae=dn->exponent+dn->digits-1;              // [0 if special]
  if (dn->digits>DECIMAL32_Pmax              // too many digits
   || ae>DECIMAL32_Emax                      // likely overflow
   || ae<DECIMAL32_Emin) {                   // likely underflow
    decContextDefault(&dc, DEC_INIT_DECIMAL32); // [no traps]
    dc.round=set->round;                     // use supplied rounding
    decNumberPlus(&dw, dn, &dc);             // (round and check)
    // [this changes -0 to 0, so enforce the sign...]
    dw.bits|=dn->bits&DECNEG;
    status=dc.status;                        // save status
    dn=&dw;                                  // use the work number
    } // maybe out of range

  if (dn->bits&DECSPECIAL) {                      // a special value
    if (dn->bits&DECINF) targ=DECIMAL_Inf<<24;
     else {                                       // sNaN or qNaN
      if ((*dn->lsu!=0 || dn->digits>1)           // non-zero coefficient
       && (dn->digits<DECIMAL32_Pmax)) {          // coefficient fits
        decDigitsToDPD(dn, &targ, 0);
        }
      if (dn->bits&DECNAN) targ|=DECIMAL_NaN<<24;
       else targ|=DECIMAL_sNaN<<24;
      } // a NaN
    } // special

   else { // is finite
    if (decNumberIsZero(dn)) {               // is a zero
      // set and clamp exponent
      if (dn->exponent<-DECIMAL32_Bias) {
        exp=0;                               // low clamp
        status|=DEC_Clamped;
        }
       else {
        exp=dn->exponent+DECIMAL32_Bias;     // bias exponent
        if (exp>DECIMAL32_Ehigh) {           // top clamp
          exp=DECIMAL32_Ehigh;
          status|=DEC_Clamped;
          }
        }
      comb=(exp>>3) & 0x18;             // msd=0, exp top 2 bits ..
      }
     else {                             // non-zero finite number
      uInt msd;                         // work
      Int pad=0;                        // coefficient pad digits

      // the dn is known to fit, but it may need to be padded
      exp=(uInt)(dn->exponent+DECIMAL32_Bias);    // bias exponent
      if (exp>DECIMAL32_Ehigh) {                  // fold-down case
        pad=exp-DECIMAL32_Ehigh;
        exp=DECIMAL32_Ehigh;                      // [to maximum]
        status|=DEC_Clamped;
        }

      // fastpath common case
      if (DECDPUN==3 && pad==0) {
        targ=BIN2DPD[dn->lsu[0]];
        if (dn->digits>3) targ|=(uInt)(BIN2DPD[dn->lsu[1]])<<10;
        msd=(dn->digits==7 ? dn->lsu[2] : 0);
        }
       else { // general case
        decDigitsToDPD(dn, &targ, pad);
        // save and clear the top digit
        msd=targ>>20;
        targ&=0x000fffff;
        }

      // create the combination field
      if (msd>=8) comb=0x18 | ((exp>>5) & 0x06) | (msd & 0x01);
             else comb=((exp>>3) & 0x18) | msd;
      }
Esempio n. 6
0
/* ------------------------------------------------------------------ */
decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
                                  decContext *set) {
  uInt status=0;                   // status accumulator
  decNumber  dw;                   // work
  decContext dc;                   // ..
  uInt *pu;                        // ..
  uInt comb, exp;                  // ..
  uInt targar[4]={0,0,0,0};        // target 128-bit
  #define targup targar[3]         // name the word with the sign

  // If the number has too many digits, or the exponent could be
  // out of range then reduce the number under the appropriate
  // constraints.  This could push the number to Infinity or zero,
  // so this check and rounding must be done before generating the
  // decimal128]
  if (!(dn->bits&DECSPECIAL)) {              // not a special value
    Int ae=dn->exponent+dn->digits-1;        // adjusted exponent
    if (dn->digits>DECIMAL128_Pmax           // too many digits
     || ae>DECIMAL128_Emax                   // likely overflow
     || ae<DECIMAL128_Emin) {                // likely underflow
      decContextDefault(&dc, DEC_INIT_DECIMAL128); // [no traps]
      dc.round=set->round;                   // use supplied rounding
      decNumberPlus(&dw, dn, &dc);           // (round and check)
      // [this changes -0 to 0, so enforce the sign...]
      dw.bits|=dn->bits&DECNEG;
      status=dc.status;                      // save status
      dn=&dw;                                // use the work number
      }
    } // maybe out of range

  if (dn->bits&DECSPECIAL) {                      // a special value
    if (dn->bits&DECINF) targup=DECIMAL_Inf<<24;
     else {                                       // sNaN or qNaN
      if ((*dn->lsu!=0 || dn->digits>1)           // non-zero coefficient
       && (dn->digits<DECIMAL128_Pmax)) {         // coefficient fits
        decDigitsToDPD(dn, targar, 0);
        }
      if (dn->bits&DECNAN) targup|=DECIMAL_NaN<<24;
       else targup|=DECIMAL_sNaN<<24;
      } // a NaN
    } // special

   else { // is finite
    if (decNumberIsZero(dn)) {               // is a zero
#if 0
      // set and clamp exponent
      if (dn->exponent<-DECIMAL128_Bias) {
        exp=0;                               // low clamp
        status|=DEC_Clamped;
        }
       else {
        exp=dn->exponent+DECIMAL128_Bias;    // bias exponent
        if (exp>DECIMAL128_Ehigh) {          // top clamp
          exp=DECIMAL128_Ehigh;
          status|=DEC_Clamped;
          }
        }
      comb=(exp>>9) & 0x18;             // msd=0, exp top 2 bits ..
#else
      exp = 0;
      comb = 0;
#endif
      }
     else {                             // non-zero finite number
      uInt msd;                         // work
      Int pad=0;                        // coefficient pad digits

      // the dn is known to fit, but it may need to be padded
      exp=(uInt)(dn->exponent+DECIMAL128_Bias);    // bias exponent
      if (exp>DECIMAL128_Ehigh) {                  // fold-down case
        pad=exp-DECIMAL128_Ehigh;
        exp=DECIMAL128_Ehigh;                      // [to maximum]
        status|=DEC_Clamped;
        }

      decDigitsToDPD(dn, targar, pad);

      // save and clear the top digit
      msd=targup>>14;
      targup&=0x00003fff;

      // create the combination field
      if (msd>=8) comb=0x18 | ((exp>>11) & 0x06) | (msd & 0x01);
             else comb=((exp>>9) & 0x18) | msd;
      }