------------------------------------------------------------------ */ decNumberOr -- OR 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
| 1798 | /* returned with Invalid_operation if a restriction is violated. */ |
| 1799 | /* ------------------------------------------------------------------ */ |
| 1800 | decNumber * decNumberOr(decNumber *res, const decNumber *lhs, |
| 1801 | const decNumber *rhs, decContext *set) { |
| 1802 | const Unit *ua, *ub; // -> operands |
| 1803 | const Unit *msua, *msub; // -> operand msus |
| 1804 | Unit *uc, *msuc; // -> result and its msu |
| 1805 | Int msudigs; // digits in res msu |
| 1806 | #if DECCHECK |
| 1807 | if (decCheckOperands(res, lhs, rhs, set)) return res; |
| 1808 | #endif |
| 1809 | |
| 1810 | if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs) |
| 1811 | || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) { |
| 1812 | decStatus(res, DEC_Invalid_operation, set); |
| 1813 | return res; |
| 1814 | } |
| 1815 | // operands are valid |
| 1816 | ua=lhs->lsu; // bottom-up |
| 1817 | ub=rhs->lsu; // .. |
| 1818 | uc=res->lsu; // .. |
| 1819 | msua=ua+D2U(lhs->digits)-1; // -> msu of lhs |
| 1820 | msub=ub+D2U(rhs->digits)-1; // -> msu of rhs |
| 1821 | msuc=uc+D2U(set->digits)-1; // -> msu of result |
| 1822 | msudigs=MSUDIGITS(set->digits); // [faster than remainder] |
| 1823 | for (; uc<=msuc; ua++, ub++, uc++) { // Unit loop |
| 1824 | Unit a, b; // extract units |
| 1825 | if (ua>msua) a=0; |
| 1826 | else a=*ua; |
| 1827 | if (ub>msub) b=0; |
| 1828 | else b=*ub; |
| 1829 | *uc=0; // can now write back |
| 1830 | if (a|b) { // maybe 1 bits to examine |
| 1831 | Int i, j; |
| 1832 | // This loop could be unrolled and/or use BIN2BCD tables |
| 1833 | for (i=0; i<DECDPUN; i++) { |
| 1834 | if ((a|b)&1) *uc=*uc+(Unit)powers[i]; // effect OR |
| 1835 | j=a%10; |
| 1836 | a=a/10; |
| 1837 | j|=b%10; |
| 1838 | b=b/10; |
| 1839 | if (j>1) { |
| 1840 | decStatus(res, DEC_Invalid_operation, set); |
| 1841 | return res; |
| 1842 | } |
| 1843 | if (uc==msuc && i==msudigs-1) break; // just did final digit |
| 1844 | } // each digit |
| 1845 | } // non-zero |
| 1846 | } // each unit |
| 1847 | // [here uc-1 is the msu of the result] |
| 1848 | res->digits=decGetDigits(res->lsu, uc-res->lsu); |
| 1849 | res->exponent=0; // integer |
| 1850 | res->bits=0; // sign=0 |
| 1851 | return res; // [no status to set] |
| 1852 | } // decNumberOr |
| 1853 | |
| 1854 | /* ------------------------------------------------------------------ */ |
| 1855 | /* decNumberPlus -- prefix plus operator */ |
nothing calls this directly
no test coverage detected