------------------------------------------------------------------ */ decGetInt -- get integer from a number */ / dn is the number [which will not be altered] */ / returns one of: */ BADINT if there is a non-zero fraction */ the converted integer
| 7538 | /* BIGODD is returned. */ |
| 7539 | /* ------------------------------------------------------------------ */ |
| 7540 | static Int decGetInt(const decNumber *dn) { |
| 7541 | Int theInt; // result accumulator |
| 7542 | const Unit *up; // work |
| 7543 | Int got; // digits (real or not) processed |
| 7544 | Int ilength=dn->digits+dn->exponent; // integral length |
| 7545 | Flag neg=decNumberIsNegative(dn); // 1 if -ve |
| 7546 | |
| 7547 | // The number must be an integer that fits in 10 digits |
| 7548 | // Assert, here, that 10 is enough for any rescale Etiny |
| 7549 | #if DEC_MAX_EMAX > 999999999 |
| 7550 | #error GetInt may need updating [for Emax] |
| 7551 | #endif |
| 7552 | #if DEC_MIN_EMIN < -999999999 |
| 7553 | #error GetInt may need updating [for Emin] |
| 7554 | #endif |
| 7555 | if (ISZERO(dn)) return 0; // zeros are OK, with any exponent |
| 7556 | |
| 7557 | up=dn->lsu; // ready for lsu |
| 7558 | theInt=0; // ready to accumulate |
| 7559 | if (dn->exponent>=0) { // relatively easy |
| 7560 | // no fractional part [usual]; allow for positive exponent |
| 7561 | got=dn->exponent; |
| 7562 | } |
| 7563 | else { // -ve exponent; some fractional part to check and discard |
| 7564 | Int count=-dn->exponent; // digits to discard |
| 7565 | // spin up whole units until reach the Unit with the unit digit |
| 7566 | for (; count>=DECDPUN; up++) { |
| 7567 | if (*up!=0) return BADINT; // non-zero Unit to discard |
| 7568 | count-=DECDPUN; |
| 7569 | } |
| 7570 | if (count==0) got=0; // [a multiple of DECDPUN] |
| 7571 | else { // [not multiple of DECDPUN] |
| 7572 | Int rem; // work |
| 7573 | // slice off fraction digits and check for non-zero |
| 7574 | #if DECDPUN<=4 |
| 7575 | theInt=QUOT10(*up, count); |
| 7576 | rem=*up-theInt*powers[count]; |
| 7577 | #else |
| 7578 | rem=*up%powers[count]; // slice off discards |
| 7579 | theInt=*up/powers[count]; |
| 7580 | #endif |
| 7581 | if (rem!=0) return BADINT; // non-zero fraction |
| 7582 | // it looks good |
| 7583 | got=DECDPUN-count; // number of digits so far |
| 7584 | up++; // ready for next |
| 7585 | } |
| 7586 | } |
| 7587 | // now it's known there's no fractional part |
| 7588 | |
| 7589 | // tricky code now, to accumulate up to 9.3 digits |
| 7590 | if (got==0) {theInt=*up; got+=DECDPUN; up++;} // ensure lsu is there |
| 7591 | |
| 7592 | if (ilength<11) { |
| 7593 | Int save=theInt; |
| 7594 | // collect any remaining unit(s) |
| 7595 | for (; got<ilength; up++) { |
| 7596 | theInt+=*up*powers[got]; |
| 7597 | got+=DECDPUN; |
no outgoing calls
no test coverage detected