MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / decNumberAnd

Function decNumberAnd

extern/decNumber/decNumber.c:785–839  ·  view source on GitHub ↗

------------------------------------------------------------------ */ 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

Source from the content-addressed store, hash-verified

783/* returned with Invalid_operation if a restriction is violated. */
784/* ------------------------------------------------------------------ */
785decNumber * 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 */

Callers

nothing calls this directly

Calls 3

decCheckOperandsFunction · 0.85
decStatusFunction · 0.85
decGetDigitsFunction · 0.85

Tested by

no test coverage detected