zmodn

A simple C++ library for integers modulo N
git clone https://git.tronto.net/zmodn
Download | Log | Files | Refs | README

commit 77de9119efbee9e65f0b50fc8b9315b6fb0910fb
parent d16656919753438a57a32f9ad6ba972c25d66b11
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Fri, 20 Mar 2026 17:59:56 +0100

Added support for _BitInt (available in clang)

Diffstat:
Abitint_wrapper.h | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Mtest | 18++++++++++++++++++
2 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/bitint_wrapper.h b/bitint_wrapper.h @@ -0,0 +1,50 @@ +#ifndef BITINT_WRAPPER_H +#define BITINT_WRAPPER_H + +#include <cstdio> +#include <iostream> + +// Wrapper class for _BitInt(N) (port of the C23 feature, compiler +// extension for C++ available in Clang and maybe GCC). This is needed +// because operator<< is not defined on _BitInt(N), apparently. + +template<uint64_t N = 128> +class BitInt { +public: + _BitInt(N) x; + + constexpr BitInt() : x{_BitInt(N)(0)} {} + constexpr BitInt(int n) : x{_BitInt(N)(n)} {} + constexpr BitInt(long long n) : x{_BitInt(N)(n)} {} + constexpr BitInt(_BitInt(N) n) : x{n} {} + constexpr auto operator<=>(const BitInt& b) const { return x <=> b.x; } + constexpr bool operator==(const BitInt& b) const = default; + constexpr BitInt operator+(const BitInt& b) const { return x + b.x; } + constexpr BitInt operator-(const BitInt& b) const { return x - b.x; } + constexpr BitInt operator*(const BitInt& b) const { return x * b.x; } + constexpr BitInt operator/(const BitInt& b) const { return x / b.x; } + constexpr BitInt operator%(const BitInt& b) const { return x % b.x; } + constexpr BitInt operator-() const { return -x; } + constexpr BitInt operator+=(const BitInt& b) { return *this = *this + b; } + constexpr BitInt operator-=(const BitInt& b) { return *this = *this - b; } + constexpr BitInt operator*=(const BitInt& b) { return *this = *this * b; } + constexpr BitInt operator/=(const BitInt& b) { return *this = *this / b; } + constexpr BitInt operator%=(const BitInt& b) { return *this = *this % b; } + + friend std::ostream& operator<<(std::ostream& os, const BitInt<N>& b) { + if (b > 0) { + std::string s; + auto bb = b; + while (bb != 0) { + char c = (bb.x % 10) + '0'; + s = c + s; + bb /= 10; + } + return os << s; + } else if (b < 0) { + return os << "-" << -b; + } else return os << "0"; + } +}; + +#endif diff --git a/test b/test @@ -12,6 +12,10 @@ exit 0 #include "zmodn.h" #include "bigint.h" +#if defined(__clang__) && __clang_major__ >= 16 +#include "bitint_wrapper.h" +#endif + #include <concepts> #include <functional> #include <iostream> @@ -479,6 +483,20 @@ public: assert_equal(inv.value().toint(), expected); } }, +#if defined(__clang__) && __clang_major__ >= 16 +{ + .name = "Zmod with BitInt", + .f = []() { + constexpr BitInt N{1000000000000LL}; // 1e12 + BitInt a{600000000000LL}; // 6e11 + BitInt b{700000000000LL}; // 7e11 + BitInt c{300000000000LL}; // 3e11 + + Zmod<N> a_modN(a), b_modN(b), c_modN(c); + assert_equal(a_modN + b_modN, c_modN); + } +}, +#endif /* { .name = "This does not compile",