/* ------------------------------------------------------------------ */ 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; }
/* ------------------------------------------------------------------ */ 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] */ }
/* ------------------------------------------------------------------ */ 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; }
/* ------------------------------------------------------------------ */ 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] }
/* ------------------------------------------------------------------ */ 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; }
/* ------------------------------------------------------------------ */ 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; }