From 234b5310c6c13e11f2ed752d0c248f47cbf72bb0 Mon Sep 17 00:00:00 2001 From: Clanmaster21 Date: Fri, 13 Nov 2020 16:53:05 +0000 Subject: [PATCH 1/2] Optimisations in arbitrary precision float multiplication --- include/lol/private/types/real.ipp | 47 ++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/include/lol/private/types/real.ipp b/include/lol/private/types/real.ipp index 26f3f1e9..299e780b 100644 --- a/include/lol/private/types/real.ipp +++ b/include/lol/private/types/real.ipp @@ -549,21 +549,40 @@ template real_t real_t::operator *(real_t const &x) const /* Accumulate low order product; no need to store it, we just * want the carry value */ uint64_t carry = 0, hicarry = 0, prev; - for (int i = 0; i < bigit_count(); ++i) + /* Calculate most significant digit of the carry, then + * calculate exactly if it's possible for carries from + * previous digits to affect the most significant one */ + for (int j = 0; j < bigit_count(); j++) + { + prev = carry; + carry += (uint64_t)m_mantissa[bigit_count() - 1 - j] + * (uint64_t)x.m_mantissa[j]; + hicarry += (carry> bigit_bits() != carry >> bigit_bits()) { - for (int j = 0; j < i + 1; j++) + carry = 0; hicarry = 0; + for (int i = 0; i < bigit_count(); ++i) { - prev = carry; - carry += (uint64_t)m_mantissa[bigit_count() - 1 - j] - * (uint64_t)x.m_mantissa[bigit_count() - 1 + j - i]; - if (carry < prev) - hicarry++; + carry >>= bigit_bits(); + carry |= hicarry << bigit_bits(); + hicarry >>= bigit_bits(); + for (int j = 0; j < i + 1; j++) + { + prev = carry; + carry += (uint64_t)m_mantissa[bigit_count() - 1 - j] + * (uint64_t)x.m_mantissa[bigit_count() - 1 + j - i]; + hicarry += (carry < prev); + } } - carry >>= bigit_bits(); - carry |= hicarry << bigit_bits(); - hicarry >>= bigit_bits(); } + carry >>= bigit_bits(); + carry |= hicarry << bigit_bits(); + hicarry >>= bigit_bits(); + + /* Multiply the other components */ for (int i = 0; i < bigit_count(); ++i) { @@ -571,15 +590,13 @@ template real_t real_t::operator *(real_t const &x) const { prev = carry; carry += (uint64_t)m_mantissa[bigit_count() - 1 - j] - * (uint64_t)x.m_mantissa[j - 1 - i]; - if (carry < prev) - hicarry++; + *(uint64_t)x.m_mantissa[j - 1 - i]; + hicarry += (carry>= bigit_bits(); carry |= hicarry << bigit_bits(); From 0261bb077465aa7e6b8091d2ecd7ccfcf43427f4 Mon Sep 17 00:00:00 2001 From: Clanmaster21 Date: Fri, 13 Nov 2020 16:54:27 +0000 Subject: [PATCH 2/2] Fix spacing --- include/lol/private/types/real.ipp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/lol/private/types/real.ipp b/include/lol/private/types/real.ipp index 299e780b..9cf359e3 100644 --- a/include/lol/private/types/real.ipp +++ b/include/lol/private/types/real.ipp @@ -590,7 +590,7 @@ template real_t real_t::operator *(real_t const &x) const { prev = carry; carry += (uint64_t)m_mantissa[bigit_count() - 1 - j] - *(uint64_t)x.m_mantissa[j - 1 - i]; + * (uint64_t)x.m_mantissa[j - 1 - i]; hicarry += (carry