32 #ifndef REAL_INFININT_HPP
33 #define REAL_INFININT_HPP
35 #include "../my_config.h"
40 #include <sys/types.h>
49 #define ZEROED_SIZE 50
54 class user_interaction;
64 #if SIZEOF_OFF_T > SIZEOF_TIME_T
65 #if SIZEOF_OFF_T > SIZEOF_SIZE_T
67 { E_BEGIN infinint_from(a); E_END(
"infinint::infinint",
"off_t") };
70 { E_BEGIN infinint_from(a); E_END(
"infinint::infinint",
"size_t") };
73 #if SIZEOF_TIME_T > SIZEOF_SIZE_T
75 { E_BEGIN infinint_from(a); E_END(
"infinint::infinint",
"time_t") };
78 { E_BEGIN infinint_from(a); E_END(
"infinint::infinint",
"size_t") };
83 { E_BEGIN; copy_from(ref); E_END(
"infinint::infinint",
"const infinint &"); }
90 { E_BEGIN
detruit(); E_END(
"infinint::~infinint",
"") };
93 { E_BEGIN
detruit(); copy_from(ref);
return *
this; E_END(
"infinint::operator =",
"") };
101 infinint & operator *= (
unsigned char arg);
103 template <
class T>
infinint power(
const T & exponent)
const;
114 { E_BEGIN
infinint ret = *
this; ++(*this);
return ret; E_END(
"infinint::operator ++",
"int") };
116 { E_BEGIN
infinint ret = *
this; --(*this);
return ret; E_END(
"infinint::operator --",
"int") };
118 { E_BEGIN
return *
this += 1; E_END(
"infinint::operator ++",
"()") };
120 { E_BEGIN
return *
this -= 1; E_END(
"infinint::operator --",
"()") };
122 U_32 operator % (U_32 arg)
const
123 { E_BEGIN
return modulo(arg); E_END(
"infinint::operator %",
"") };
128 template <
class T>
void unstack(T &v)
129 { E_BEGIN infinint_unstack_to(v); E_END(
"infinint::unstack",
typeid(v).name()) }
131 infinint get_storage_size()
const {
return field->size(); };
134 unsigned char operator [] (
const infinint & position)
const;
145 static bool is_system_big_endian();
148 static const int TG = 4;
150 enum endian { big_endian, little_endian, not_initialized };
151 typedef unsigned char group[TG];
155 bool is_valid()
const;
158 void copy_from(
const infinint & ref);
160 void make_at_least_as_wider_as(
const infinint & ref);
161 template <
class T>
void infinint_from(T a);
162 template <
class T> T max_val_of(T x);
163 template <
class T>
void infinint_unstack_to(T &a);
164 template <
class T> T modulo(T arg)
const;
165 signed int difference(
const infinint & b)
const;
170 static endian used_endian;
171 static U_8 zeroed_field[ZEROED_SIZE];
172 static void setup_endian();
176 #define OPERATOR(OP) inline bool operator OP (const infinint &a, const infinint &b) \
179 return a.difference(b) OP 0; \
180 E_END("operator OP", "infinint, infinint") \
191 infinint operator - (const infinint &, const infinint &);
192 infinint operator * (const infinint &, const infinint &);
193 infinint operator * (const infinint &, const
unsigned char);
194 infinint operator * (const
unsigned char, const infinint &);
195 infinint operator / (const infinint &, const infinint &);
196 infinint operator % (const infinint &, const infinint &);
197 infinint operator & (const infinint & a, const infinint & bit);
198 infinint operator | (const infinint & a, const infinint & bit);
199 infinint operator ^ (const infinint & a, const infinint & bit);
200 infinint operator >> (const infinint & a, U_32 bit);
201 infinint operator >> (const infinint & a, const infinint & bit);
202 infinint operator << (const infinint & a, U_32 bit);
203 infinint operator << (const infinint & a, const infinint & bit);
204 void euclide(infinint a, const infinint &b, infinint &q, infinint &r);
205 template <class T> inline
void euclide(T a, T b, T & q, T &r)
212 inline infinint & infinint::operator /= (
const infinint & ref)
217 E_END(
"infinint::operator /=",
"")
220 inline infinint & infinint::operator %= (
const infinint & ref)
225 E_END(
"infinint::operator %=",
"")
233 template <
class T> infinint infinint::power(
const T & exponent)
const
236 for(T count = 0; count < exponent; ++count)
242 template <
class T> T infinint::modulo(T arg)
const
245 infinint tmp = *
this % infinint(arg);
247 unsigned char *debut = (
unsigned char *)(&ret);
248 unsigned char *ptr = debut +
sizeof(T) - 1;
249 storage::iterator it = tmp.field->rbegin();
251 while(it != tmp.field->rend() && ptr >= debut)
260 while(it != tmp.field->rend())
267 if(used_endian == little_endian)
268 int_tools_swap_bytes(debut,
sizeof(T));
271 E_END(
"infinint::modulo",
"")
275 template <
class T>
void infinint::infinint_from(T a)
278 U_I size =
sizeof(a);
280 unsigned char *ptr, *fin;
282 if(used_endian == not_initialized)
285 if(used_endian == little_endian)
288 ptr = (
unsigned char *)(&a) + (size - 1);
289 fin = (
unsigned char *)(&a) - 1;
294 ptr = (
unsigned char *)(&a);
295 fin = (
unsigned char *)(&a) + size;
298 while(ptr != fin && *ptr == 0)
310 field =
new storage(size);
313 storage::iterator it = field->begin();
321 if(it != field->end())
325 throw Ememory(
"template infinint::infinint_from");
327 E_END(
"infinint::infinint_from",
"")
330 template <
class T> T infinint::max_val_of(T x)
338 x = int_tools_rotate_right_one_bit(x);
345 template <
class T>
void infinint::infinint_unstack_to(T &a)
351 static const T max_T = max_val_of(a);
352 infinint step = max_T - a;
357 unsigned char *debut = (
unsigned char *)&transfert;
358 unsigned char *ptr = debut +
sizeof(transfert) - 1;
359 storage::iterator it = field->rbegin();
361 while(ptr >= debut && it != field->rend())
368 if(used_endian == little_endian)
369 int_tools_swap_bytes(debut,
sizeof(transfert));
378 E_END(
"infinint::infinint_unstack_to",
"")