From 97c94018402c95f2ed1f59645f4b1cbdd255b978 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Tue, 21 Jan 2025 08:03:15 +0100 Subject: Final examples for templates --- templates/zmodn-3.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 templates/zmodn-3.cpp (limited to 'templates/zmodn-3.cpp') diff --git a/templates/zmodn-3.cpp b/templates/zmodn-3.cpp new file mode 100644 index 0000000..ca73783 --- /dev/null +++ b/templates/zmodn-3.cpp @@ -0,0 +1,57 @@ +#include "bigint.h" + +#include +#include +#include +#include + +template +std::tuple extended_gcd(T a, T b) { + if (b == 0) return {a, 1, 0}; + auto [g, x, y] = extended_gcd(b, a%b); + return {g, y, x - y*(a/b)}; +} + +template +requires (N > 1) +class Zmod { +public: + decltype(N) value; + + Zmod(decltype(N) z) : value{(z%N + N) % N} {} + + Zmod operator+(const Zmod& z) const { return value + z.value; } + Zmod operator-(const Zmod& z) const { return value - z.value; } + Zmod operator*(const Zmod& z) const { return value * z.value; } + + std::optional inverse() const { + auto [g, a, _] = extended_gcd(value, N); + return g == 1 ? Zmod(a) : std::optional{}; + } + + std::optional operator/(const Zmod& d) const { + auto i = d.inverse(); + return i ? (*this) * i.value() : i; + } + + std::optional operator/=(const Zmod& d) { + auto q = *this / d; + return q ? (*this = q.value()) : q; + } +}; + +int main() { + constexpr BigInt N("1000000000000000000000000000000"); + Zmod x(BigInt("123456781234567812345678")); + Zmod y(BigInt("987654321987654321")); + + std::cout << x.value << " * " + << y.value << " (mod " << N << ") = " + << (x * y).value << std::endl; + + // The following gives a compile error on the first % operation + // constexpr double M = 3.14; + // Zmod z(4); + + return 0; +} -- cgit v1.3