Go to the documentation of this file.00001
00002
00003
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef _CHOMP_STRUCT_INTEGER_H_
00038 #define _CHOMP_STRUCT_INTEGER_H_
00039
00040 #include "chomp/system/config.h"
00041 #include "chomp/system/textfile.h"
00042
00043 #include <iostream>
00044
00045 namespace chomp {
00046 namespace homology {
00047
00048
00049
00050 class primeint;
00051 class integer;
00052
00053
00054
00055
00056
00057
00060 class primeint
00061 {
00062 public:
00065 primeint (int_t k = 0);
00066
00068 primeint &operator = (const primeint &p);
00069
00072 primeint &operator = (int_t k);
00073
00076 operator int_t () const;
00077
00078 private:
00080 int_t n;
00081
00082 };
00083
00084
00085
00086 inline primeint::operator int_t () const
00087 {
00088 return n;
00089 }
00090
00091 inline primeint &primeint::operator = (const primeint &p)
00092 {
00093 n = p. n;
00094 return *this;
00095 }
00096
00097
00098
00100 inline std::ostream &operator << (std::ostream &out, const primeint &p)
00101 {
00102 out << static_cast<int_t> (p);
00103 return out;
00104 }
00105
00109 inline std::istream &operator >> (std::istream &in, primeint &p)
00110 {
00111 int_t n;
00112 in >> n;
00113 p = n;
00114 return in;
00115 }
00116
00117
00118
00119
00120
00121
00127 typedef signed short numbertype;
00128
00134 class integer
00135 {
00136 public:
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 integer &operator = (int n);
00148
00149
00150
00151
00152 static int initialize (int n);
00153
00154
00155
00156 int delta (void) const;
00157
00158
00159 integer normalized () const;
00160
00161
00162 integer operator - () const;
00163 integer &operator += (const integer &n);
00164 integer &operator *= (const integer &n);
00165 integer operator + (const integer &n) const;
00166 integer operator * (const integer &n) const;
00167 integer operator / (const integer &n) const;
00168 integer operator % (const integer &n) const;
00169 int operator == (const integer &n) const;
00170
00171 static const char *ringname ();
00172 static const char *ringsymbol ();
00173
00174 friend std::ostream &operator << (std::ostream &out, const integer &n);
00175 friend bool operator < (const integer &x, const integer &y);
00176 friend bool operator > (const integer &x, const integer &y);
00177
00178 protected:
00179
00180 static int p;
00181
00182
00183 numbertype num;
00184
00185
00186 static int cut_down (int n);
00187 static int is_prime (int n);
00188 static int prime_number (int n);
00189 static unsigned invert (unsigned n, unsigned q);
00190
00191 };
00192
00193
00194
00195 inline int integer::cut_down (int n)
00196 {
00197 if (n >= 0)
00198 if (n < p)
00199 return n;
00200 else
00201 return (n % p);
00202 else
00203 {
00204 int num = p - ((-n) % p);
00205 if (num == p)
00206 return 0;
00207 else
00208 return num;
00209 }
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 inline integer &integer::operator = (int n)
00243 {
00244 if (p)
00245 num = (numbertype) cut_down (n);
00246 else
00247 {
00248 num = (numbertype) n;
00249 if ((long) num != (long) n)
00250 throw "Number out of range at assignment.";
00251 }
00252 return *this;
00253 }
00254
00255 inline integer integer::operator / (const integer &n) const
00256 {
00257 integer result;
00258 if (p)
00259 result = num * (int) invert (n. num, p);
00260 else
00261 result. num = (numbertype) (num / n. num);
00262 return result;
00263 }
00264
00265 inline integer integer::operator % (const integer &n) const
00266 {
00267 integer result;
00268 if (p)
00269 result. num = 0;
00270 else
00271 result = num % n. num;
00272 return result;
00273 }
00274
00275 inline integer integer::operator - () const
00276 {
00277 if (p)
00278 {
00279 integer negative;
00280 negative. num = (numbertype) (p - num);
00281 return negative;
00282 }
00283 else
00284 {
00285 numbertype result = (numbertype) -num;
00286 if ((long) result + (long) num != 0)
00287 throw "Number out of range (unary -).";
00288 integer intresult;
00289 intresult = result;
00290 return intresult;
00291 }
00292 }
00293
00294 inline integer &integer::operator += (const integer &n)
00295 {
00296 if (!p)
00297 if (((n. num >= 0) && (num + n. num < num)) ||
00298 ((n. num < 0) && (num + n. num > num)))
00299 throw "Number out of range (+).";
00300 num += n. num;
00301 if (p)
00302 if (num >= p)
00303 num -= (numbertype) p;
00304 return *this;
00305 }
00306
00307 inline integer &integer::operator *= (const integer &n)
00308 {
00309 if (p)
00310 {
00311 long result = (long) num * (long) n. num;
00312 if (result >= 0)
00313 num = (numbertype) (result % p);
00314 else
00315 {
00316 num = (numbertype) (p - ((-result) % p));
00317 if (num == p)
00318 num = 0;
00319 }
00320 }
00321 else
00322 {
00323 long result = (long) num * (long) (n. num);
00324 num = (numbertype) result;
00325 if ((long) num != result)
00326 throw "Number out of range (*).";
00327 }
00328 return *this;
00329 }
00330
00331 inline integer integer::operator + (const integer &n) const
00332 {
00333 integer m (n);
00334 m += *this;
00335 return m;
00336 }
00337
00338 inline integer integer::operator * (const integer &n) const
00339 {
00340 integer m (n);
00341 m *= *this;
00342 return m;
00343 }
00344
00345 inline int integer::operator == (const integer &n) const
00346 {
00347 return (n. num == num);
00348 }
00349
00350 inline std::ostream &operator << (std::ostream &out, const integer &n)
00351 {
00352 out << (long) n. num;
00353 return out;
00354 }
00355
00356 inline std::istream &operator >> (std::istream &in, integer &n)
00357 {
00358 long number;
00359 in >> number;
00360 if (!in)
00361 return in;
00362 n = number;
00363 return in;
00364 }
00365
00366 inline int operator != (const integer &n, const integer &m)
00367 {
00368 return (!(n == m));
00369 }
00370
00371 inline int operator == (const integer &n, int m)
00372 {
00373 integer intm;
00374 intm = m;
00375 return (n == intm);
00376 }
00377
00378 inline int operator != (const integer &n, int m)
00379 {
00380 return !(n == m);
00381 }
00382
00383 inline integer operator - (const integer &n, const integer &m)
00384 {
00385 return (n + -m);
00386 }
00387
00388 inline int integer::initialize (int n)
00389 {
00390 p = prime_number (n);
00391 return p;
00392 }
00393
00394 inline int integer::delta (void) const
00395 {
00396 if (p)
00397 return (num ? 1 : 0);
00398 else
00399 return ((num >= 0) ? num : -num);
00400 }
00401
00402 inline integer integer::normalized (void) const
00403 {
00404 integer n;
00405 if (num < 0)
00406 n. num = (numbertype) (-num);
00407 else
00408 n. num = num;
00409 return n;
00410 }
00411
00412 inline bool operator < (const integer &x, const integer &y)
00413 {
00414 return (x. num < y. num);
00415 }
00416
00417 inline bool operator > (const integer &x, const integer &y)
00418 {
00419 return (x. num > y. num);
00420 }
00421
00422
00423 }
00424 }
00425
00426 #endif // _CHOMP_STRUCT_INTEGER_H_
00427
00429