------------------------------------------------------------------ */ decNumberAnd -- AND two Numbers, digitwise */ / This computes C = A & B */ / res is C, the result. C may be A and/or B (e.g., X=X&X) */ lhs is A */ rhs is B
| 783 | /* returned with Invalid_operation if a restriction is violated. */ |
| 784 | /* ------------------------------------------------------------------ */ |
| 785 | decNumber * decNumberAnd(decNumber *res, const decNumber *lhs, |
| 786 | const decNumber *rhs, decContext *set) { |
| 787 | const Unit *ua, *ub; // -> operands |
| 788 | const Unit *msua, *msub; // -> operand msus |
| 789 | Unit *uc, *msuc; // -> result and its msu |
| 790 | Int msudigs; // digits in res msu |
| 791 | #if DECCHECK |
| 792 | if (decCheckOperands(res, lhs, rhs, set)) return res; |
| 793 | #endif |
| 794 | |
| 795 | if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs) |
| 796 | || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) { |
| 797 | decStatus(res, DEC_Invalid_operation, set); |
| 798 | return res; |
| 799 | } |
| 800 | |
| 801 | // operands are valid |
| 802 | ua=lhs->lsu; // bottom-up |
| 803 | ub=rhs->lsu; // .. |
| 804 | uc=res->lsu; // .. |
| 805 | msua=ua+D2U(lhs->digits)-1; // -> msu of lhs |
| 806 | msub=ub+D2U(rhs->digits)-1; // -> msu of rhs |
| 807 | msuc=uc+D2U(set->digits)-1; // -> msu of result |
| 808 | msudigs=MSUDIGITS(set->digits); // [faster than remainder] |
| 809 | for (; uc<=msuc; ua++, ub++, uc++) { // Unit loop |
| 810 | Unit a, b; // extract units |
| 811 | if (ua>msua) a=0; |
| 812 | else a=*ua; |
| 813 | if (ub>msub) b=0; |
| 814 | else b=*ub; |
| 815 | *uc=0; // can now write back |
| 816 | if (a|b) { // maybe 1 bits to examine |
| 817 | Int i, j; |
| 818 | *uc=0; // can now write back |
| 819 | // This loop could be unrolled and/or use BIN2BCD tables |
| 820 | for (i=0; i<DECDPUN; i++) { |
| 821 | if (a&b&1) *uc=*uc+(Unit)powers[i]; // effect AND |
| 822 | j=a%10; |
| 823 | a=a/10; |
| 824 | j|=b%10; |
| 825 | b=b/10; |
| 826 | if (j>1) { |
| 827 | decStatus(res, DEC_Invalid_operation, set); |
| 828 | return res; |
| 829 | } |
| 830 | if (uc==msuc && i==msudigs-1) break; // just did final digit |
| 831 | } // each digit |
| 832 | } // both OK |
| 833 | } // each unit |
| 834 | // [here uc-1 is the msu of the result] |
| 835 | res->digits=decGetDigits(res->lsu, uc-res->lsu); |
| 836 | res->exponent=0; // integer |
| 837 | res->bits=0; // sign=0 |
| 838 | return res; // [no status to set] |
| 839 | } // decNumberAnd |
| 840 | |
| 841 | /* ------------------------------------------------------------------ */ |
| 842 | /* decNumberCompare -- compare two Numbers */ |
nothing calls this directly
no test coverage detected