[libcxx-commits] [libcxx] [libc++] Implement std::gcd using the binary version (PR #77747)

via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jan 12 02:48:57 PST 2024


================
@@ -50,9 +52,25 @@ struct __ct_abs<_Result, _Source, false> {
 };
 
 template <class _Tp>
-_LIBCPP_CONSTEXPR _LIBCPP_HIDDEN _Tp __gcd(_Tp __m, _Tp __n) {
+_LIBCPP_CONSTEXPR _LIBCPP_HIDDEN _Tp __gcd(_Tp __a, _Tp __b) {
   static_assert((!is_signed<_Tp>::value), "");
-  return __n == 0 ? __m : std::__gcd<_Tp>(__n, __m % __n);
+  if (__a == 0)
+    return __b;
+  if (__b == 0)
+    return __a;
+
+  int __az    = std::__countr_zero(__a);
+  int __bz    = std::__countr_zero(__b);
+  int __shift = std::min(__az, __bz);
+  __b >>= __bz;
+  while (__a != 0) {
+    __a >>= __az;
+    _Tp __absdiff = __a > __b ? __a - __b : __b - __a;
+    __b           = std::min(__a, __b);
+    __a           = __absdiff;
+    __az          = std::__countr_zero(__absdiff);
+  }
+  return __b << __shift;
----------------
AdvenamTacet wrote:

Could you add a comment explaining the algorithm and with links to further materials?

https://github.com/llvm/llvm-project/pull/77747


More information about the libcxx-commits mailing list