------------------------------------------------------------------ */ decShiftToMost -- shift digits in array towards most significant */ / uar is the array */ digits is the count of digits in use in the array */ shift is the number of zeros to pad with (least significant); */ it must be zero or positive
| 6681 | /* be large enough to hold the result, after shifting). */ |
| 6682 | /* ------------------------------------------------------------------ */ |
| 6683 | static Int decShiftToMost(Unit *uar, Int digits, Int shift) { |
| 6684 | Unit *target, *source, *first; // work |
| 6685 | Int cut; // odd 0's to add |
| 6686 | uInt next; // work |
| 6687 | |
| 6688 | if (shift==0) return digits; // [fastpath] nothing to do |
| 6689 | if ((digits+shift)<=DECDPUN) { // [fastpath] single-unit case |
| 6690 | *uar=(Unit)(*uar*powers[shift]); |
| 6691 | return digits+shift; |
| 6692 | } |
| 6693 | |
| 6694 | next=0; // all paths |
| 6695 | source=uar+D2U(digits)-1; // where msu comes from |
| 6696 | target=source+D2U(shift); // where upper part of first cut goes |
| 6697 | cut=DECDPUN-MSUDIGITS(shift); // where to slice |
| 6698 | if (cut==0) { // unit-boundary case |
| 6699 | for (; source>=uar; source--, target--) *target=*source; |
| 6700 | } |
| 6701 | else { |
| 6702 | first=uar+D2U(digits+shift)-1; // where msu of source will end up |
| 6703 | for (; source>=uar; source--, target--) { |
| 6704 | // split the source Unit and accumulate remainder for next |
| 6705 | #if DECDPUN<=4 |
| 6706 | uInt quot=QUOT10(*source, cut); |
| 6707 | uInt rem=*source-quot*powers[cut]; |
| 6708 | next+=quot; |
| 6709 | #else |
| 6710 | uInt rem=*source%powers[cut]; |
| 6711 | next+=*source/powers[cut]; |
| 6712 | #endif |
| 6713 | if (target<=first) *target=(Unit)next; // write to target iff valid |
| 6714 | next=rem*powers[DECDPUN-cut]; // save remainder for next Unit |
| 6715 | } |
| 6716 | } // shift-move |
| 6717 | |
| 6718 | // propagate any partial unit to one below and clear the rest |
| 6719 | for (; target>=uar; target--) { |
| 6720 | *target=(Unit)next; |
| 6721 | next=0; |
| 6722 | } |
| 6723 | return digits+shift; |
| 6724 | } // decShiftToMost |
| 6725 | |
| 6726 | /* ------------------------------------------------------------------ */ |
| 6727 | /* decShiftToLeast -- shift digits in array towards least significant */ |
no outgoing calls
no test coverage detected