------------------------------------------------------------------ */ decCanonical -- copy a decFloat, making canonical */ / result gets the canonicalized df */ df is the decFloat to copy and make canonical */ returns result */ / This is exposed via decFloatCanonical for Double and
| 73 | /* This works on specials, too; no error or exception is possible. */ |
| 74 | /* ------------------------------------------------------------------ */ |
| 75 | static decFloat * decCanonical(decFloat *result, const decFloat *df) { |
| 76 | uInt encode, precode, dpd; // work |
| 77 | uInt inword, uoff, canon; // .. |
| 78 | Int n; // counter (down) |
| 79 | if (df!=result) *result=*df; // effect copy if needed |
| 80 | if (DFISSPECIAL(result)) { |
| 81 | if (DFISINF(result)) return decInfinity(result, df); // clean Infinity |
| 82 | // is a NaN |
| 83 | DFWORD(result, 0)&=~ECONNANMASK; // clear ECON except selector |
| 84 | if (DFISCCZERO(df)) return result; // coefficient continuation is 0 |
| 85 | // drop through to check payload |
| 86 | } |
| 87 | // return quickly if the coefficient continuation is canonical |
| 88 | { // declare block |
| 89 | #if DOUBLE |
| 90 | uInt sourhi=DFWORD(df, 0); |
| 91 | uInt sourlo=DFWORD(df, 1); |
| 92 | if (CANONDPDOFF(sourhi, 8) |
| 93 | && CANONDPDTWO(sourhi, sourlo, 30) |
| 94 | && CANONDPDOFF(sourlo, 20) |
| 95 | && CANONDPDOFF(sourlo, 10) |
| 96 | && CANONDPDOFF(sourlo, 0)) return result; |
| 97 | #elif QUAD |
| 98 | uInt sourhi=DFWORD(df, 0); |
| 99 | uInt sourmh=DFWORD(df, 1); |
| 100 | uInt sourml=DFWORD(df, 2); |
| 101 | uInt sourlo=DFWORD(df, 3); |
| 102 | if (CANONDPDOFF(sourhi, 4) |
| 103 | && CANONDPDTWO(sourhi, sourmh, 26) |
| 104 | && CANONDPDOFF(sourmh, 16) |
| 105 | && CANONDPDOFF(sourmh, 6) |
| 106 | && CANONDPDTWO(sourmh, sourml, 28) |
| 107 | && CANONDPDOFF(sourml, 18) |
| 108 | && CANONDPDOFF(sourml, 8) |
| 109 | && CANONDPDTWO(sourml, sourlo, 30) |
| 110 | && CANONDPDOFF(sourlo, 20) |
| 111 | && CANONDPDOFF(sourlo, 10) |
| 112 | && CANONDPDOFF(sourlo, 0)) return result; |
| 113 | #endif |
| 114 | } // block |
| 115 | |
| 116 | // Loop to repair a non-canonical coefficent, as needed |
| 117 | inword=DECWORDS-1; // current input word |
| 118 | uoff=0; // bit offset of declet |
| 119 | encode=DFWORD(result, inword); |
| 120 | for (n=DECLETS-1; n>=0; n--) { // count down declets of 10 bits |
| 121 | dpd=encode>>uoff; |
| 122 | uoff+=10; |
| 123 | if (uoff>32) { // crossed uInt boundary |
| 124 | inword--; |
| 125 | encode=DFWORD(result, inword); |
| 126 | uoff-=32; |
| 127 | dpd|=encode<<(10-uoff); // get pending bits |
| 128 | } |
| 129 | dpd&=0x3ff; // clear uninteresting bits |
| 130 | if (dpd<0x16e) continue; // must be canonical |
| 131 | canon=BIN2DPD[DPD2BIN[dpd]]; // determine canonical declet |
| 132 | if (canon==dpd) continue; // have canonical declet |
no test coverage detected