void multiplyHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2, U_64 * result, IDATA length) { /* assumes result is large enough to hold product */ U_64 *temp; U_32 *resultIn32; IDATA count, index; if (length1 < length2) { temp = arg1; arg1 = arg2; arg2 = temp; count = length1; length1 = length2; length2 = count; } memset (result, 0, sizeof (U_64) * length); /* length1 > length2 */ resultIn32 = (U_32 *) result; index = -1; for (count = 0; count < length2; ++count) { simpleMultiplyAddHighPrecision (arg1, length1, LOW_IN_U64 (arg2[count]), resultIn32 + (++index)); simpleMultiplyAddHighPrecision (arg1, length1, HIGH_IN_U64 (arg2[count]), resultIn32 + (++index)); } }
void multiplyHighPrecision (uint64_t * arg1, int32_t length1, uint64_t * arg2, int32_t length2, uint64_t * result, int32_t length) { /* assumes result is large enough to hold product */ uint64_t* temp; uint32_t* resultIn32; int32_t count, index; if (length1 < length2) { temp = arg1; arg1 = arg2; arg2 = temp; count = length1; length1 = length2; length2 = count; } memset (result, 0, sizeof (uint64_t) * length); /* length1 > length2 */ resultIn32 = reinterpret_cast<uint32_t*>(result); index = -1; for (count = 0; count < length2; ++count) { simpleMultiplyAddHighPrecision (arg1, length1, LOW_IN_U64 (arg2[count]), resultIn32 + (++index)); #if __BYTE_ORDER == __LITTLE_ENDIAN simpleMultiplyAddHighPrecision(arg1, length1, HIGH_IN_U64(arg2[count]), resultIn32 + (++index)); #else simpleMultiplyAddHighPrecisionBigEndianFix(arg1, length1, HIGH_IN_U64(arg2[count]), resultIn32 + (++index)); #endif } }
U_32 simpleAppendDecimalDigitHighPrecision (U_64 * arg1, IDATA length, U_64 digit) { /* assumes digit is less than 32 bits */ U_64 arg; IDATA index = 0; digit <<= 32; do { arg = LOW_IN_U64 (arg1[index]); digit = HIGH_IN_U64 (digit) + TIMES_TEN (arg); LOW_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (digit); arg = HIGH_IN_U64 (arg1[index]); digit = HIGH_IN_U64 (digit) + TIMES_TEN (arg); HIGH_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (digit); } while (++index < length); return HIGH_U32_FROM_VAR (digit); }
uint32_t simpleAppendDecimalDigitHighPrecision (uint64_t * arg1, int32_t length, uint64_t digit) { /* assumes digit is less than 32 bits */ uint64_t arg; int32_t index = 0; digit <<= 32; do { arg = LOW_IN_U64 (arg1[index]); digit = HIGH_IN_U64 (digit) + TIMES_TEN (arg); LOW_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (digit); arg = HIGH_IN_U64 (arg1[index]); digit = HIGH_IN_U64 (digit) + TIMES_TEN (arg); HIGH_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (digit); } while (++index < length); return HIGH_U32_FROM_VAR (digit); }