From 60ef82986d26bf836b6ef76a9fb01892f3a1e1f2 Mon Sep 17 00:00:00 2001 From: Michael Hemmer Date: Fri, 2 Mar 2007 12:02:31 +0000 Subject: [PATCH] rm file Modular_type added test for class Modular added separate test for class Modular_traits --- .gitattributes | 1 + Modular_arithmetic/include/CGAL/Modular.h | 285 ++++++++++++++++- .../include/CGAL/Modular_traits.h | 15 +- .../include/CGAL/Modular_type.h | 295 ------------------ Modular_arithmetic/include/CGAL/modular_gcd.h | 1 - .../test/Modular_arithmetic/Modular.C | 109 ++++--- .../test/Modular_arithmetic/Modular_traits.C | 58 ++++ .../test/Modular_arithmetic/makefile | 1 + 8 files changed, 417 insertions(+), 348 deletions(-) delete mode 100644 Modular_arithmetic/include/CGAL/Modular_type.h create mode 100644 Modular_arithmetic/test/Modular_arithmetic/Modular_traits.C diff --git a/.gitattributes b/.gitattributes index bcdfb321f80..988be748224 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1388,6 +1388,7 @@ Modifier/doc_tex/Modifier/idraw/modifier.eps -text svneol=unset#application/post Modifier/doc_tex/Modifier/idraw/modifier.pdf -text svneol=unset#application/pdf Modifier/doc_tex/Modifier/modifier.gif -text svneol=unset#image/gif Modifier/doc_tex/Modifier/modifier_small.gif -text svneol=unset#image/gif +Modular_arithmetic/test/Modular_arithmetic/Modular_traits.C -text Nef_2/demo/Nef_2/filtered_homogeneous_data/complex.nef -text svneol=native#application/octet-stream Nef_2/demo/Nef_2/filtered_homogeneous_data/symmdif.nef -text svneol=native#application/octet-stream Nef_2/demo/Nef_2/help/index.html svneol=native#text/html diff --git a/Modular_arithmetic/include/CGAL/Modular.h b/Modular_arithmetic/include/CGAL/Modular.h index 885a1041477..4a9b029911a 100644 --- a/Modular_arithmetic/include/CGAL/Modular.h +++ b/Modular_arithmetic/include/CGAL/Modular.h @@ -12,14 +12,282 @@ #define CGAL_MODULAR_H 1 #include -#include -#include #include namespace CGAL { -// I/O +class Modular; + +Modular operator + (const Modular&); +Modular operator - (const Modular&); +Modular operator + (const Modular&, const Modular&); +Modular operator - (const Modular&, const Modular&); +Modular operator * (const Modular&, const Modular&); +Modular operator / (const Modular&, const Modular&); +std::ostream& operator << (std::ostream& os, const Modular& p); +std::istream& operator >> (std::istream& is, Modular& p); + +/*! \ingroup CGAL_Modular_traits + * \brief This class represents the Field Z mod p. + * + * This class uses the type double for representation. + * Therefore the value of p is restricted to primes less than 2^26. + * By default p is set to 67111067. + * + * It provides the standard operators +,-,*,/ as well as in&output. + * + * \see Modular_traits + */ +class Modular{ + +public: + typedef Modular Self; + typedef Modular NT; + +private: + static const double CST_CUT = ((3.0*(1<<30))*(1<<21)); +private: + + static int prime_int; + static double prime; + static double prime_inv; + + + /* Quick integer rounding, valid if a<2^51. for double */ + static inline + double MOD_round (double a){ +#ifdef LiS_HAVE_LEDA + return ( (a + CST_CUT) - CST_CUT); +#else + // TODO: + // In order to get rid of the volatile double + // one should call: + // CGAL/FPU.h : inline void force_ieee_double_precision() + // the problem is where and when it should be called ? + // and whether on should restore the old behaviour + // since it changes the global behaviour of doubles. + // Note that this code works if LEDA is present, since leda automatically + // changes this behaviour in the desired way. + volatile double b = (a + CST_CUT); + return b - CST_CUT; +#endif + } + + + /* Big modular reduction (e.g. after multiplication) */ + static inline + double MOD_reduce (double a){ + return a - prime * MOD_round(a * prime_inv); + } + + + /* Little modular reduction (e.g. after a simple addition). */ + static inline + double MOD_soft_reduce (double a){ + double b = 2*a; + return (b>prime) ? a-prime : + ((b<-prime) ? a+prime : a); + } + + /* -a */ + static inline + double MOD_negate(double a){ + return MOD_soft_reduce(-a); + } + + + /* a*b */ + static inline + double MOD_mul (double a, double b){ + double c = a*b; + return MOD_reduce(c); + } + + + /* a+b */ + static inline + double MOD_add (double a, double b){ + double c = a+b; + return MOD_soft_reduce(c); + } + + + /* a^-1, using Bezout (extended Euclidian algorithm). */ + static inline + double MOD_inv (double ri1){ + double bi = 0.0; + double bi1 = 1.0; + double ri = prime; + double p, tmp, tmp2; + + Real_embeddable_traits::Abs double_abs; + while (double_abs(ri1) != 1.0) + { + p = MOD_round(ri/ri1); + tmp = bi - p * bi1; + tmp2 = ri - p * ri1; + bi = bi1; + ri = ri1; + bi1 = tmp; + ri1 = tmp2; + }; + + return ri1 * MOD_soft_reduce(bi1); /* Quicker !!!! */ + } + + /* a/b */ + static inline + double MOD_div (double a, double b){ + return MOD_mul(a, MOD_inv(b)); + } + +public: + /*! \brief sets the current prime. + * + * Note that you are going to change a static member! + * \pre p is prime, but we abstained from such a test. + * \pre 0 < p < 2^26 + * + */ + static int + set_current_prime(int p){ + int old_prime = prime_int; + prime_int = p; + prime = (double)p; + prime_inv = (double)1/prime; + return old_prime; + } + /*! \brief return the current prime. */ + static int get_current_prime(){ + return prime_int; + } + int get_value() const{ + return int(x_); + } + +private: + double x_; + +public: + + //! Explicit constructor of Modular, from int + Modular(int n = 0){ + x_= MOD_reduce(n); + } + + //! Explicit constructor of Modular, from long + Modular(long n){ + x_= MOD_reduce(n); + } + + //! Access operator for x, \c const + const double& x() const { return x_; } + //! Access operator for x + double& x() { return x_; } + + Self& operator += (const Self& p2) { + x() = MOD_add(x(),p2.x()); + return (*this); + } + + Self& operator -= (const Self& p2){ + x() = MOD_add(x(),MOD_negate(p2.x())); + return (*this); + } + + Self& operator *= (const Self& p2){ + x() = MOD_mul(x(),p2.x()); + return (*this); + } + + Self& operator /= (const Self& p2) { + x() = MOD_div(x(),p2.x()); + return (*this); + } + + friend Self operator + (const Self&); + friend Self operator - (const Self&); + friend Self operator + (const Self&, const Self&); + friend Self operator - (const Self&, const Self&); + friend Self operator * (const Self&, const Self&); + friend Self operator / (const Self& p1, const Self& p2); +}; + +inline Modular operator + (const Modular& p1) +{ return p1; } + +inline Modular operator - (const Modular& p1){ + typedef Modular MOD; + Modular r; + r.x() = MOD::MOD_negate(p1.x()); + return r; +} + +inline Modular operator + (const Modular& p1,const Modular& p2) { + typedef Modular MOD; + Modular r; + r.x() = MOD::MOD_add(p1.x(),p2.x()); + return r; +} + +inline Modular operator - (const Modular& p1, const Modular& p2) { + return p1+(-p2); +} + +inline Modular operator * (const Modular& p1, const Modular& p2) { + typedef Modular MOD; + Modular r; + r.x() = MOD::MOD_mul(p1.x(),p2.x()); + return r; +} + +inline Modular operator / (const Modular& p1, const Modular& p2) { + typedef Modular MOD; + Modular r; + r.x() = MOD::MOD_div(p1.x(),p2.x()); + return r; +} + +inline bool operator == (const Modular& p1, const Modular& p2) +{ return ( p1.x()==p2.x() ); } + +inline bool operator != (const Modular& p1, const Modular& p2) +{ return ( p1.x()!=p2.x() ); } + +// left hand side +inline bool operator == (int num, const Modular& p) +{ return ( Modular(num) == p );} +inline bool operator != (int num, const Modular& p) +{ return ( Modular(num) != p );} + +// right hand side +inline bool operator == (const Modular& p, int num) +{ return ( Modular(num) == p );} +inline bool operator != (const Modular& p, int num) +{ return ( Modular(num) != p );} + +// left hand side +inline Modular operator + (int num, const Modular& p2) +{ return (Modular(num) + p2); } +inline Modular operator - (int num, const Modular& p2) +{ return (Modular(num) - p2); } +inline Modular operator * (int num, const Modular& p2) +{ return (Modular(num) * p2); } +inline Modular operator / (int num, const Modular& p2) +{ return (Modular(num)/p2); } + +// right hand side +inline Modular operator + (const Modular& p1, int num) +{ return (p1 + Modular(num)); } +inline Modular operator - (const Modular& p1, int num) +{ return (p1 - Modular(num)); } +inline Modular operator * (const Modular& p1, int num) +{ return (p1 * Modular(num)); } +inline Modular operator / (const Modular& p1, int num) +{ return (p1 / Modular(num)); } + +// I/O inline std::ostream& operator << (std::ostream& os, const Modular& p) { typedef Modular MOD; os <<"("<< p.x()<<"%"<> (std::istream& is, Modular& p) { * \ingroup CGAL_NT_traits_spec */ template <> -class Algebraic_structure_traits - : public Algebraic_structure_traits_base< Modular ,Field_tag >{}; - - +struct Algebraic_structure_traits + : public Algebraic_structure_traits_base< Modular ,Field_tag >{ + typedef CGAL::Tag_true Is_exact; +}; }///namespace CGAL +//TODO: move to src/ +#include <./src_Modular.C> + #endif //#ifnedef CGAL_MODULAR_H 1 diff --git a/Modular_arithmetic/include/CGAL/Modular_traits.h b/Modular_arithmetic/include/CGAL/Modular_traits.h index 24dd2de52ca..c9d4da87791 100644 --- a/Modular_arithmetic/include/CGAL/Modular_traits.h +++ b/Modular_arithmetic/include/CGAL/Modular_traits.h @@ -3,7 +3,8 @@ #ifndef CGAL_MODULAR_TRAITS_H #define CGAL_MODULAR_TRAITS_H 1 - +#include +#include #include #include #include @@ -189,6 +190,18 @@ public: }; }; +// TODO: put this into Modular_arithmetic/src/ +int primes[64] = { + 67089287,67089299,67089329,67089377,67089461,67089469,67089479,67089511, + 67089527,67089541,67089577,67089587,67089619,67089683,67089697,67089707, + 67089721,67089733,67089739,67089751,67089793,67089809,67089811,67089829, + 67089839,67089857,67089877,67089907,67089943,67089949,67089989,67090013, + 67090027,67090031,67090033,67090043,67090061,67090073,67090091,67090099, + 67090117,67090129,67090151,67090171,67090189,67090207,67090217,67090223, + 67090229,67090237,67090259,67090271,67090307,67090321,67090343,67090351, + 67090399,67090403,67090411,67090433,67090451,67090459,67090489,67090519 +}; + }///namespace CGAL #endif //#ifnedef CGAL_MODULAR_TRAITS_H 1 diff --git a/Modular_arithmetic/include/CGAL/Modular_type.h b/Modular_arithmetic/include/CGAL/Modular_type.h deleted file mode 100644 index 0c5734c8ca6..00000000000 --- a/Modular_arithmetic/include/CGAL/Modular_type.h +++ /dev/null @@ -1,295 +0,0 @@ -//Author(s) : Michael Hemmer -// Sylvain Pion - - -// defines the pure type Modular, i.e. no CGAL support - -#ifndef CGAL_MODULAR_TYPE_H -#define CGAL_MODULAR_TYPE_H 1 - -#include - -namespace CGAL { - -int primes[] = { // 64 primes - 67089287,67089299,67089329,67089377,67089461,67089469,67089479,67089511, - 67089527,67089541,67089577,67089587,67089619,67089683,67089697,67089707, - 67089721,67089733,67089739,67089751,67089793,67089809,67089811,67089829, - 67089839,67089857,67089877,67089907,67089943,67089949,67089989,67090013, - 67090027,67090031,67090033,67090043,67090061,67090073,67090091,67090099, - 67090117,67090129,67090151,67090171,67090189,67090207,67090217,67090223, - 67090229,67090237,67090259,67090271,67090307,67090321,67090343,67090351, - 67090399,67090403,67090411,67090433,67090451,67090459,67090489,67090519 -}; - -class Modular; - -Modular operator + (const Modular&); -Modular operator - (const Modular&); -Modular operator + (const Modular&, const Modular&); -Modular operator - (const Modular&, const Modular&); -Modular operator * (const Modular&, const Modular&); -Modular operator / (const Modular&, const Modular&); - -std::ostream& operator << (std::ostream& os, const Modular& p); -std::istream& operator >> (std::istream& is, Modular& p); - -/*! \ingroup CGAL_Modular_traits - * \brief This class represents the Field Z mod p. - * - * This class uses the type double for representation. - * Therefore the value of p is restricted to primes less than 2^26. - * By default p is set to 67111067. - * - * It provides the standard operators +,-,*,/ as well as in&output. - * - * \see Modular_traits - */ -class Modular{ -public: - typedef Modular Self; - typedef Modular NT; - -private: - static const double CST_CUT = ((3.0*(1<<30))*(1<<21)); -private: - - static int prime_int; - static double prime; - static double prime_inv; - - - /* Quick integer rounding, valid if a<2^51. for double */ - static inline - double MOD_round (double a){ -#ifdef LiS_HAVE_LEDA - return ( (a + CST_CUT) - CST_CUT); -#else - // TODO: - // In order to get rid of the volatile double - // one should call: - // CGAL/FPU.h : inline void force_ieee_double_precision() - // the problem is where and when it should be called ? - // and whether on should restore the old behaviour - // since it changes the global behaviour of doubles. - // Note that this code works if LEDA is present, since leda automatically - // changes this behaviour in the desired way. - volatile double b = (a + CST_CUT); - return b - CST_CUT; -#endif - } - - - /* Big modular reduction (e.g. after multiplication) */ - static inline - double MOD_reduce (double a){ - return a - prime * MOD_round(a * prime_inv); - } - - - /* Little modular reduction (e.g. after a simple addition). */ - static inline - double MOD_soft_reduce (double a){ - double b = 2*a; - return (b>prime) ? a-prime : - ((b<-prime) ? a+prime : a); - } - - /* -a */ - static inline - double MOD_negate(double a){ - return MOD_soft_reduce(-a); - } - - - /* a*b */ - static inline - double MOD_mul (double a, double b){ - double c = a*b; - return MOD_reduce(c); - } - - - /* a+b */ - static inline - double MOD_add (double a, double b){ - double c = a+b; - return MOD_soft_reduce(c); - } - - - /* a^-1, using Bezout (extended Euclidian algorithm). */ - static inline - double MOD_inv (double ri1){ - double bi = 0.0; - double bi1 = 1.0; - double ri = prime; - double p, tmp, tmp2; - - Real_embeddable_traits::Abs double_abs; - while (double_abs(ri1) != 1.0) - { - p = MOD_round(ri/ri1); - tmp = bi - p * bi1; - tmp2 = ri - p * ri1; - bi = bi1; - ri = ri1; - bi1 = tmp; - ri1 = tmp2; - }; - - return ri1 * MOD_soft_reduce(bi1); /* Quicker !!!! */ - } - - /* a/b */ - static inline - double MOD_div (double a, double b){ - return MOD_mul(a, MOD_inv(b)); - } - -public: - /*! \brief sets the current prime. - * - * Note that you are going to change a static member! - * \pre p is prime, but we abstained from such a test. - * \pre 0 < p < 2^26 - * - */ - static void - set_current_prime(int p){ - prime_int=p; - prime = (double)p; - prime_inv = (double)1/prime; - } - /*! \brief return the current prime. */ - static int get_current_prime(){ - return prime_int; - } - int get_value() const{ - return int(x_); - } - -private: - double x_; - -public: - - //! Explicit constructor of Modular, from int - Modular(int n = 0){ - x_= MOD_reduce(n); - } - - //! Explicit constructor of Modular, from long - Modular(long n){ - x_= MOD_reduce(n); - } - - //! Access operator for x, \c const - const double& x() const { return x_; } - //! Access operator for x - double& x() { return x_; } - - Self& operator += (const Self& p2) { - x() = MOD_add(x(),p2.x()); - return (*this); - } - - Self& operator -= (const Self& p2){ - x() = MOD_add(x(),MOD_negate(p2.x())); - return (*this); - } - - Self& operator *= (const Self& p2){ - x() = MOD_mul(x(),p2.x()); - return (*this); - } - - Self& operator /= (const Self& p2) { - x() = MOD_div(x(),p2.x()); - return (*this); - } - - friend Self operator + (const Self&); - friend Self operator - (const Self&); - friend Self operator + (const Self&, const Self&); - friend Self operator - (const Self&, const Self&); - friend Self operator * (const Self&, const Self&); - friend Self operator / (const Self& p1, const Self& p2); -}; - -inline Modular operator + (const Modular& p1) -{ return p1; } - -inline Modular operator - (const Modular& p1){ - typedef Modular MOD; - Modular r; - r.x() = MOD::MOD_negate(p1.x()); - return r; -} - -inline Modular operator + (const Modular& p1,const Modular& p2) { - typedef Modular MOD; - Modular r; - r.x() = MOD::MOD_add(p1.x(),p2.x()); - return r; -} - -inline Modular operator - (const Modular& p1, const Modular& p2) { - return p1+(-p2); -} - -inline Modular operator * (const Modular& p1, const Modular& p2) { - typedef Modular MOD; - Modular r; - r.x() = MOD::MOD_mul(p1.x(),p2.x()); - return r; -} - -inline Modular operator / (const Modular& p1, const Modular& p2) { - typedef Modular MOD; - Modular r; - r.x() = MOD::MOD_div(p1.x(),p2.x()); - return r; -} - -inline bool operator == (const Modular& p1, const Modular& p2) -{ return ( p1.x()==p2.x() ); } - -inline bool operator != (const Modular& p1, const Modular& p2) -{ return ( p1.x()!=p2.x() ); } - -// left hand side -inline bool operator == (int num, const Modular& p) -{ return ( Modular(num) == p );} -inline bool operator != (int num, const Modular& p) -{ return ( Modular(num) != p );} - -// right hand side -inline bool operator == (const Modular& p, int num) -{ return ( Modular(num) == p );} -inline bool operator != (const Modular& p, int num) -{ return ( Modular(num) != p );} - -// left hand side -inline Modular operator + (int num, const Modular& p2) -{ return (Modular(num) + p2); } -inline Modular operator - (int num, const Modular& p2) -{ return (Modular(num) - p2); } -inline Modular operator * (int num, const Modular& p2) -{ return (Modular(num) * p2); } -inline Modular operator / (int num, const Modular& p2) -{ return (Modular(num)/p2); } - -// right hand side -inline Modular operator + (const Modular& p1, int num) -{ return (p1 + Modular(num)); } -inline Modular operator - (const Modular& p1, int num) -{ return (p1 - Modular(num)); } -inline Modular operator * (const Modular& p1, int num) -{ return (p1 * Modular(num)); } -inline Modular operator / (const Modular& p1, int num) -{ return (p1 / Modular(num)); } - -}// namespace CGAL - -#endif // CGAL_MODULAR_H 1 diff --git a/Modular_arithmetic/include/CGAL/modular_gcd.h b/Modular_arithmetic/include/CGAL/modular_gcd.h index b57d31a342f..eedcec2e757 100644 --- a/Modular_arithmetic/include/CGAL/modular_gcd.h +++ b/Modular_arithmetic/include/CGAL/modular_gcd.h @@ -9,7 +9,6 @@ #define CGAL_MODULAR_GCD_H 1 #include -#include #include #include #include diff --git a/Modular_arithmetic/test/Modular_arithmetic/Modular.C b/Modular_arithmetic/test/Modular_arithmetic/Modular.C index a107329888c..0b821a06345 100644 --- a/Modular_arithmetic/test/Modular_arithmetic/Modular.C +++ b/Modular_arithmetic/test/Modular_arithmetic/Modular.C @@ -5,55 +5,76 @@ */ #include -#include #include -#include <./src_Modular.C> +#include -#ifdef CGAL_USE_LEDA -#include -#include -#endif // CGAL_USE_LEDA -#ifdef CGAL_USE_CORE -#include -#include -#endif // CGAL_USE_CORE - -#include - -#include - - -template -void test_modular_traits(){ - - typedef CGAL::Modular Modular; - typedef CGAL::Modular_traits MT; - typedef typename MT::Modular_NT Modular_NT; - typedef typename MT::Modular_image Modular_image; - typedef typename MT::Is_convertible Is_convertible; - typedef typename MT::NT NT; - - CGAL_test_assert( - !(::boost::is_same::value)); - CGAL_test_assert( - (::boost::is_same::value)); - CGAL_test_assert( - (::boost::is_same::value)); - - Modular::set_current_prime(7); - Modular_image modular_image; - CGAL_test_assert(modular_image(TESTT(21)) == Modular_NT(0)); - CGAL_test_assert(modular_image(TESTT(22)) == Modular_NT(1)); - CGAL_test_assert(modular_image(TESTT(777777722)) == Modular_NT(1)); -} int main() { - test_modular_traits(); -// test_modular_traits(); - for (int i = 0 ; i < 64 ; i++){ - std::cout <(); + + int old_prime = NT::get_current_prime(); + CGAL_test_assert(old_prime == NT::set_current_prime(7)); + CGAL_test_assert(7 == NT::get_current_prime()); + + NT x(4),y(5),z(12),t; + + // operator == + CGAL_test_assert(!(x==y)); + CGAL_test_assert(y==z); + // operator != + CGAL_test_assert(x!=y); + CGAL_test_assert(!(z!=y)); + + // constructor + CGAL_test_assert(NT(2)==NT(2-5*NT::get_current_prime())); + CGAL_test_assert(NT(2)==NT(2+5*NT::get_current_prime())); + + // operator unary + + CGAL_test_assert((+x)==x); + // operator unary - + CGAL_test_assert(-x==x*NT(-1)); + + // operator binary + + CGAL_test_assert((x+y)==NT(2)); + // operator binary - + CGAL_test_assert((x-y)==NT(6)); + // operator * + CGAL_test_assert((x*y)==NT(6)); + // operator / + CGAL_test_assert((x/y)==NT(5)); + + + // operator += + t=x; CGAL_test_assert((x+y)==(t+=y)); + // operator -= + t=x; CGAL_test_assert((x-y)==(t-=y)); + // operator *= + t=x; CGAL_test_assert((x*y)==(t*=y)); + // operator /= + t=x; CGAL_test_assert((x/y)==(t/=y)); + + // left/right Hand + // operator == + CGAL_test_assert(x==4); + CGAL_test_assert(5==y); + // operator != + CGAL_test_assert(x!=5); + CGAL_test_assert(4!=y); + // operator + + t=x; CGAL_test_assert((x+5)==(5+x)); + // operator - + t=x; CGAL_test_assert((x-5)==(4-y)); + // operator * + t=x; CGAL_test_assert((x*5)==(5*x)); + // operator = + t=x; CGAL_test_assert((x/5)==(4/y)); + + //cout << x << endl; + } diff --git a/Modular_arithmetic/test/Modular_arithmetic/Modular_traits.C b/Modular_arithmetic/test/Modular_arithmetic/Modular_traits.C new file mode 100644 index 00000000000..2599959b90b --- /dev/null +++ b/Modular_arithmetic/test/Modular_arithmetic/Modular_traits.C @@ -0,0 +1,58 @@ +// Author(s) : Michael Hemmer + +/*! \file CGAL/Modular.C + test for number type modul +*/ + +#include +#include +#include + +#include <./src_Modular.C> + +#ifdef CGAL_USE_LEDA +#include +#include +#endif // CGAL_USE_LEDA +#ifdef CGAL_USE_CORE +#include +#include +#endif // CGAL_USE_CORE + +#include + +#include + + +template +void test_modular_traits(){ + + typedef CGAL::Modular Modular; + typedef CGAL::Modular_traits MT; + typedef typename MT::Modular_NT Modular_NT; + typedef typename MT::Modular_image Modular_image; + typedef typename MT::Is_convertible Is_convertible; + typedef typename MT::NT NT; + + CGAL_test_assert( + !(::boost::is_same::value)); + CGAL_test_assert( + (::boost::is_same::value)); + CGAL_test_assert( + (::boost::is_same::value)); + + Modular::set_current_prime(7); + Modular_image modular_image; + CGAL_test_assert(modular_image(TESTT(21)) == Modular_NT(0)); + CGAL_test_assert(modular_image(TESTT(22)) == Modular_NT(1)); + CGAL_test_assert(modular_image(TESTT(777777722)) == Modular_NT(1)); +} + +int main() +{ + test_modular_traits(); +// test_modular_traits(); + for (int i = 0 ; i < 64 ; i++){ + std::cout <