| 3266 | /* ------------------------------------------------------------------ */ |
| 3267 | #define PHALF (ROUNDUP(DECPMAX/2, 4)) // half length, rounded up |
| 3268 | decFloat * decFloatRotate(decFloat *result, |
| 3269 | const decFloat *dfl, const decFloat *dfr, |
| 3270 | decContext *set) { |
| 3271 | Int rotate; // dfr as an Int |
| 3272 | uByte buf[DECPMAX+PHALF]; // coefficient + half |
| 3273 | uInt digits, savestat; // work |
| 3274 | bcdnum num; // .. |
| 3275 | uByte *ub; // .. |
| 3276 | |
| 3277 | if (DFISNAN(dfl)||DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set); |
| 3278 | if (!DFISINT(dfr)) return decInvalid(result, set); |
| 3279 | digits=decFloatDigits(dfr); // calculate digits |
| 3280 | if (digits>2) return decInvalid(result, set); // definitely out of range |
| 3281 | rotate=DPD2BIN[DFWORD(dfr, DECWORDS-1)&0x3ff]; // is in bottom declet |
| 3282 | if (rotate>DECPMAX) return decInvalid(result, set); // too big |
| 3283 | // [from here on no error or status change is possible] |
| 3284 | if (DFISINF(dfl)) return decInfinity(result, dfl); // canonical |
| 3285 | // handle no-rotate cases |
| 3286 | if (rotate==0 || rotate==DECPMAX) return decCanonical(result, dfl); |
| 3287 | // a real rotate is needed: 0 < rotate < DECPMAX |
| 3288 | // reduce the rotation to no more than half to reduce copying later |
| 3289 | // (for QUAD in fact half + 2 digits) |
| 3290 | if (DFISSIGNED(dfr)) rotate=-rotate; |
| 3291 | if (abs(rotate)>PHALF) { |
| 3292 | if (rotate<0) rotate=DECPMAX+rotate; |
| 3293 | else rotate=rotate-DECPMAX; |
| 3294 | } |
| 3295 | // now lay out the coefficient, leaving room to the right or the |
| 3296 | // left depending on the direction of rotation |
| 3297 | ub=buf; |
| 3298 | if (rotate<0) ub+=PHALF; // rotate right, so space to left |
| 3299 | GETCOEFF(dfl, ub); |
| 3300 | // copy half the digits to left or right, and set num.msd |
| 3301 | if (rotate<0) { |
| 3302 | memcpy(buf, buf+DECPMAX, PHALF); |
| 3303 | num.msd=buf+PHALF+rotate; |
| 3304 | } |
| 3305 | else { |
| 3306 | memcpy(buf+DECPMAX, buf, PHALF); |
| 3307 | num.msd=buf+rotate; |
| 3308 | } |
| 3309 | // fill in rest of num |
| 3310 | num.lsd=num.msd+DECPMAX-1; |
| 3311 | num.sign=DFWORD(dfl, 0)&DECFLOAT_Sign; |
| 3312 | num.exponent=GETEXPUN(dfl); |
| 3313 | savestat=set->status; // record |
| 3314 | decFinalize(result, &num, set); |
| 3315 | set->status=savestat; // restore |
| 3316 | return result; |
| 3317 | } // decFloatRotate |
| 3318 | |
| 3319 | /* ------------------------------------------------------------------ */ |
| 3320 | /* decFloatSameQuantum -- test decFloats for same quantum */ |
nothing calls this directly
no test coverage detected