// Rascal, the Advanced Scientific CALculator // Copyright (C) 2001, Sebastian Ritterbusch (Rascal@Ritterbusch.de) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more detauls. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // Long Integer Library // (C) 1999 Jochen Suckfüll // (C) 2001 Sebastian Ritterbusch #ifndef LANGZAHL_HPP_INCLUDED #define LANGZAHL_HPP_INCLUDED #include #include using std::string; #include #include #include #undef RAND_MAX #define RAND_MAX 100000000 #define ILOG232 0.104 #define LOG232 9.633 #define MAX(a,b) (a>b?a:b) #define LONG32 int extern class init_rand { public: init_rand() { srand(time(0)); } } randomstate; class lsize { private: int s; public: lsize(int i) throw():s(i) { } ~lsize() { }; int size() const { return s; } }; class langzahl { private: int longs; int sign; LONG32 *dat; public: langzahl() throw():longs(0),sign(0),dat(0) { }; langzahl(const LONG32) throw(); langzahl(const lsize &) throw(); langzahl(const string &) throw(); langzahl(const langzahl &) throw(); ~langzahl() throw() { delete [] dat; } void kuerze() throw(); friend istream &operator >>(istream &,langzahl &) throw(); friend string &operator >>(string &,langzahl &) throw(); friend ostream &operator <<(ostream &,const langzahl &) throw(); friend string &operator <<(string &,const langzahl &) throw(); langzahl &operator =(const langzahl &) throw(); langzahl &operator =(LONG32) throw(); langzahl &operator =(const char *) throw(); friend bool operator ==(const langzahl &,const langzahl &) throw(); friend bool operator !=(const langzahl &,const langzahl &) throw(); friend bool operator <=(const langzahl &,const langzahl &) throw(); friend bool operator >=(const langzahl &,const langzahl &) throw(); friend bool operator <(const langzahl &,const langzahl &) throw(); friend bool operator >(const langzahl &,const langzahl &) throw(); friend inline bool operator ==(const langzahl &a,LONG32 b) throw() { return a==langzahl(b); } friend inline bool operator !=(const langzahl &a,LONG32 b) throw() { return a!=langzahl(b); } friend inline bool operator <=(const langzahl &a,LONG32 b) throw() { return a<=langzahl(b); } friend inline bool operator >=(const langzahl &a,LONG32 b) throw() { return a>=langzahl(b); } friend inline bool operator <(const langzahl &a,LONG32 b) throw() { return a(const langzahl &a,LONG32 b) throw() { return a>langzahl(b); } friend inline bool operator ==(LONG32 a,const langzahl & b) throw() { return langzahl(a)==b; } friend inline bool operator !=(LONG32 a,const langzahl & b) throw() { return langzahl(a)!=b; } friend inline bool operator <=(LONG32 a,const langzahl & b) throw() { return langzahl(a)<=b; } friend inline bool operator >=(LONG32 a,const langzahl & b) throw() { return langzahl(a)>=b; } friend inline bool operator <(LONG32 a,const langzahl & b) throw() { return langzahl(a)(LONG32 a,const langzahl & b) throw() { return langzahl(a)>b; } friend bool eqzero(const langzahl &) throw(); friend bool grzero(const langzahl &) throw(); friend bool ltzero(const langzahl &) throw(); friend langzahl operator -(const langzahl &) throw(); friend langzahl operator %(langzahl,langzahl) throw(); friend inline langzahl operator %(const langzahl &a,LONG32 b) throw() { return a%langzahl(b); } friend inline langzahl operator %(LONG32 a,const langzahl &b) throw() { return langzahl(a)%b; } friend langzahl operator /(langzahl,langzahl) throw(); friend inline langzahl operator /(const langzahl &a,LONG32 b) throw() { return a/langzahl(b); } friend inline langzahl operator /(LONG32 a,const langzahl &b) throw() { return langzahl(a)/b; } friend langzahl _llplus(const langzahl &,const langzahl &) throw(); friend langzahl _llminus(const langzahl &,const langzahl &) throw(); friend langzahl operator +(const langzahl &,const langzahl &) throw(); friend inline langzahl operator +(const langzahl &a,LONG32 b) throw() { return a+langzahl(b); } friend inline langzahl operator +(LONG32 a,const langzahl &b) throw() { return langzahl(a)+b; } friend langzahl operator -(const langzahl &,const langzahl &) throw(); friend inline langzahl operator -(const langzahl &a,LONG32 b) throw() { return a-langzahl(b); } friend inline langzahl operator -(LONG32 a,const langzahl &b) throw() { return langzahl(a)-b; } friend langzahl operator *(const langzahl &,const langzahl &) throw(); friend inline langzahl operator *(const langzahl &a,LONG32 b) throw() { return a*langzahl(b); } friend inline langzahl operator *(LONG32 a,const langzahl &b) throw() { return langzahl(a)*b; } langzahl &operator +=(const langzahl &) throw(); langzahl &operator -=(const langzahl &) throw(); langzahl &operator *=(const langzahl &) throw(); langzahl &operator %=(const langzahl &) throw(); // addm(a,b,m)=(a+b)%m friend langzahl addm(const langzahl &,const langzahl &,const langzahl &) throw(); // subm(a,b,m)=(a-b)%m friend langzahl subm(const langzahl &,const langzahl &,const langzahl &) throw(); // multm(a,b,m)=(a*b)%m friend langzahl multm(const langzahl &,const langzahl &,const langzahl &) throw(); friend langzahl potm(const langzahl &,const int,const langzahl &) throw(); friend langzahl potm(const langzahl &,const langzahl &,const langzahl &) throw(); friend langzahl pow(const langzahl &,const langzahl &) throw(); friend langzahl pow(const langzahl &,const int) throw(); friend langzahl operator *=(langzahl &,const int) throw(); friend langzahl operator /=(langzahl &,const int) throw(); // ggT liefert immer einen positiven Wert friend langzahl ggT(const langzahl &,const langzahl &) throw(); friend void div2(langzahl &) throw(); friend void mul2(langzahl &) throw(); // Rabin-Miller-Pseudoprimtest // Ist n pseudoprim zur Basis a? // 0-> sicher nicht, 1-> *wahrscheinlich* schon friend bool pprim(const langzahl &n,const langzahl &a) throw(); // erzeuge zufaellige langzahl mit n longs friend langzahl lrandom(const int n) throw(); friend langzahl fak(LONG32) throw(); // Pollard p-1 Methode zur Faktorisierung friend langzahl pollard(const langzahl &) throw(); int operator !() const throw(); template friend T convert(const langzahl & a) throw(); inline operator double(void) const { return convert(*this); } }; template T convert(const langzahl & a) throw() { T dest(0); T mul(1); for(int i=0;i