use boost::ordered_field_operators1

modular arithmetic needs ieee double precision
This commit is contained in:
Michael Hemmer 2008-04-28 11:31:48 +00:00
parent 97b300b576
commit e42a22537a
3 changed files with 89 additions and 82 deletions

View File

@ -27,14 +27,19 @@
CGAL_BEGIN_NAMESPACE CGAL_BEGIN_NAMESPACE
namespace CGALi{
struct Modular_arithmetic_needs_ieee_double_precision{
Modular_arithmetic_needs_ieee_double_precision(){
CGAL::force_ieee_double_precision();
}
};
}
class Modular; class Modular;
Modular operator + (const Modular&); Modular operator + (const 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::ostream& operator << (std::ostream& os, const Modular& p);
std::istream& operator >> (std::istream& is, Modular& p); std::istream& operator >> (std::istream& is, Modular& p);
@ -50,7 +55,9 @@ std::istream& operator >> (std::istream& is, Modular& p);
* *
* \see Modular_traits * \see Modular_traits
*/ */
class Modular{ class Modular:
boost::ordered_field_operators1< Modular,
boost::ordered_field_operators2< Modular, int > >{
public: public:
typedef Modular Self; typedef Modular Self;
@ -58,6 +65,8 @@ public:
private: private:
static const double CST_CUT; static const double CST_CUT;
static const CGALi::Modular_arithmetic_needs_ieee_double_precision
modular_arithmetic_needs_ieee_double_precision;
private: private:
static int prime_int; static int prime_int;
@ -201,28 +210,40 @@ public:
x() = MOD_add(x(),p2.x()); x() = MOD_add(x(),p2.x());
return (*this); return (*this);
} }
Self& operator -= (const Self& p2){ Self& operator -= (const Self& p2){
x() = MOD_add(x(),MOD_negate(p2.x())); x() = MOD_add(x(),MOD_negate(p2.x()));
return (*this); return (*this);
} }
Self& operator *= (const Self& p2){ Self& operator *= (const Self& p2){
x() = MOD_mul(x(),p2.x()); x() = MOD_mul(x(),p2.x());
return (*this); return (*this);
} }
Self& operator /= (const Self& p2) { Self& operator /= (const Self& p2) {
x() = MOD_div(x(),p2.x()); x() = MOD_div(x(),p2.x());
return (*this); return (*this);
} }
//
Self& operator += (int p2) {
x() = MOD_add(x(),Modular(p2).x());
return (*this);
}
Self& operator -= (int p2){
x() = MOD_add(x(),Modular(-p2).x());
return (*this);
}
Self& operator *= (int p2){
x() = MOD_mul(x(),Modular(p2).x());
return (*this);
}
Self& operator /= (int p2) {
x() = MOD_div(x(),Modular(p2).x());
return (*this);
}
friend Self operator + (const Self&); friend Self operator + (const Self&);
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) inline Modular operator + (const Modular& p1)
@ -235,68 +256,17 @@ inline Modular operator - (const Modular& p1){
return r; 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) inline bool operator == (const Modular& p1, const Modular& p2)
{ return ( p1.x()==p2.x() ); } { return ( p1.x()==p2.x() ); }
inline bool operator == (const Modular& p1, int p2)
{ return ( p1 == Modular(p2) ); }
inline bool operator != (const Modular& p1, const Modular& p2)
{ return ( p1.x()!=p2.x() ); }
// left hand side inline bool operator < (const Modular& p1, const Modular& p2)
inline bool operator == (int num, const Modular& p) { return ( p1.x() < p2.x() ); }
{ return ( Modular(num) == p );} inline bool operator < (const Modular& p1, int p2)
inline bool operator != (int num, const Modular& p) { return ( p1.x() < Modular(p2).x() ); }
{ 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 // I/O
inline std::ostream& operator << (std::ostream& os, const Modular& p) { inline std::ostream& operator << (std::ostream& os, const Modular& p) {
@ -305,7 +275,6 @@ inline std::ostream& operator << (std::ostream& os, const Modular& p) {
return os; return os;
} }
inline std::istream& operator >> (std::istream& is, Modular& p) { inline std::istream& operator >> (std::istream& is, Modular& p) {
typedef Modular MOD; typedef Modular MOD;
char ch; char ch;

View File

@ -27,10 +27,13 @@
#include <CGAL/Modular_arithmetic/Modular_type.h> #include <CGAL/Modular_arithmetic/Modular_type.h>
namespace CGAL{ namespace CGAL{
int Modular::prime_int = 67111067;
double Modular::prime =67111067.0;
double Modular::prime_inv =1/67111067.0;
const double Modular::CST_CUT = std::ldexp( 3., 51 ); int Modular::prime_int = 67111067;
double Modular::prime =67111067.0;
double Modular::prime_inv =1/67111067.0;
const double Modular::CST_CUT = std::ldexp( 3., 51 );
const CGALi::Modular_arithmetic_needs_ieee_double_precision
Modular::modular_arithmetic_needs_ieee_double_precision
= CGALi::Modular_arithmetic_needs_ieee_double_precision();
} }

View File

@ -9,6 +9,8 @@
#include <CGAL/Modular.h> #include <CGAL/Modular.h>
#include <CGAL/Test/_test_algebraic_structure.h> #include <CGAL/Test/_test_algebraic_structure.h>
#include <CGAL/Arithmetic_kernel.h>
#include <CGAL/number_utils.h>
int main() int main()
{ {
@ -76,6 +78,39 @@ int main()
//cout << x << endl; //cout << x << endl;
assert(7 == NT::set_current_prime(old_prime));
typedef CGAL::Arithmetic_kernel AK;
typedef AK::Integer Integer;
Integer int_x(7);
Integer prime(NT::get_current_prime());
CGAL::Modular mod_x(7);
for(int i = 0; i < 10000; i++){
assert(mod_x == CGAL::modular_image(int_x));
int_x *= int_x; int_x = CGAL::mod(int_x, prime);
mod_x *= mod_x;
assert(mod_x == CGAL::modular_image(int_x));
int_x += int_x; int_x = CGAL::mod(int_x, prime);
mod_x += mod_x;
assert(mod_x == CGAL::modular_image(int_x));
assert(mod_x == CGAL::modular_image(int_x));
int_x *= int_x; int_x = CGAL::mod(int_x, prime);
mod_x *= mod_x;
assert(mod_x == CGAL::modular_image(int_x));
int_x -= int_x; int_x = CGAL::mod(int_x, prime);
mod_x -= mod_x;
}
// CGAL::force_ieee_double_precision();
{
CGAL::Modular::set_current_prime(67111043);
CGAL::Modular x(-33546401);
CGAL::Modular y(23950928);
CGAL::Modular q = CGAL::integral_division(x,y);
assert(x == q*y);
}
} }