------------------------------------------------------------------ */ to-int32 -- conversion to Int or uInt */ / dn is the decNumber to convert */ set is the context for reporting errors */ returns the converted decNumber, or 0 if Invalid is set */ / Invalid is set if the decNumber does not have exp
| 367 | /* it is a NaN, Infinite, or out-of-range. */ |
| 368 | /* ------------------------------------------------------------------ */ |
| 369 | Int decNumberToInt32(const decNumber *dn, decContext *set) { |
| 370 | #if DECCHECK |
| 371 | if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0; |
| 372 | #endif |
| 373 | |
| 374 | // special or too many digits, or bad exponent |
| 375 | if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0) ; // bad |
| 376 | else { // is a finite integer with 10 or fewer digits |
| 377 | Int d; // work |
| 378 | const Unit *up; // .. |
| 379 | uInt hi=0, lo; // .. |
| 380 | up=dn->lsu; // -> lsu |
| 381 | lo=*up; // get 1 to 9 digits |
| 382 | #if DECDPUN>1 // split to higher |
| 383 | hi=lo/10; |
| 384 | lo=lo%10; |
| 385 | #endif |
| 386 | up++; |
| 387 | // collect remaining Units, if any, into hi |
| 388 | for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1]; |
| 389 | // now low has the lsd, hi the remainder |
| 390 | if (hi>214748364 || (hi==214748364 && lo>7)) { // out of range? |
| 391 | // most-negative is a reprieve |
| 392 | if (dn->bits&DECNEG && hi==214748364 && lo==8) return 0x80000000; |
| 393 | // bad -- drop through |
| 394 | } |
| 395 | else { // in-range always |
| 396 | Int i=X10(hi)+lo; |
| 397 | if (dn->bits&DECNEG) return -i; |
| 398 | return i; |
| 399 | } |
| 400 | } // integer |
| 401 | decContextSetStatus(set, DEC_Invalid_operation); // [may not return] |
| 402 | return 0; |
| 403 | } // decNumberToInt32 |
| 404 | |
| 405 | uInt decNumberToUInt32(const decNumber *dn, decContext *set) { |
| 406 | #if DECCHECK |
nothing calls this directly
no test coverage detected