00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __ARAGELI_big_int_h__
00020 #define __ARAGELI_big_int_h__
00021
00022 #include "config.hpp"
00023
00024 #include <cstddef>
00025 #include <iostream>
00026 #include <cstdlib>
00027 #include <string>
00028 #include <cctype>
00029 #include <cmath>
00030 #include <limits>
00031
00032 #include "frwrddecl.hpp"
00033
00034 #include "type_traits.hpp"
00035 #include "type_pair_traits.hpp"
00036 #include "exception.hpp"
00037 #include "factory.hpp"
00038 #include "powerest.hpp"
00039 #include "intalg.hpp"
00040 #include "bigar.hpp"
00041
00042 #include "std_import.hpp"
00043
00054 namespace Arageli
00055 {
00056
00057 namespace _Internal
00058 {
00059
00060 void xdivide (big_int& a, const big_int& b, const big_int& c, big_int& res);
00061 }
00062
00063
00064
00065
00066
00067
00068
00069
00070
00072 class big_int
00073 {
00074
00075
00076 typedef _Internal::digit digit;
00077
00078 public:
00079
00081
00082 class exception : public virtual Arageli::exception
00083 {
00084 std::string msg_m;
00085 public:
00086
00088 exception () {}
00089
00091
00092 exception (const std::string& msg_a) : msg_m(msg_a) {}
00093
00095
00096 virtual std::string msg () const { return msg_m; }
00097 };
00098
00099
00100
00101
00102
00104
00106 class incorrect_string : public exception, public Arageli::incorrect_string
00107 {
00108 public:
00109 incorrect_string (const std::string& msg_a)
00110 : Arageli::incorrect_string(msg_a) {}
00111
00112 virtual std::string msg () const { return Arageli::incorrect_string::msg(); }
00113 };
00114
00115
00117
00118 big_int () { alloc_zero(); }
00119
00121
00124 big_int (const char* str);
00125
00127
00130 big_int (const big_int& b)
00131 {
00132 ARAGELI_ASSERT_0(this != &b);
00133 b.number->refs++;
00134 number = b.number;
00135 }
00136
00137
00139
00144 template <typename T>
00145 big_int (const rational<T>& x)
00146 {
00147 alloc_zero();
00148 *this = x.numerator()/x.denominator();
00149 }
00150
00153
00154 big_int (char x) { from_native_int(x); }
00155 big_int (signed char x) { from_native_int(x); }
00156 big_int (unsigned char x) { from_native_int(x); }
00157 big_int (signed short x) { from_native_int(x); }
00158 big_int (unsigned short x) { from_native_int(x); }
00159 big_int (signed int x) { from_native_int(x); }
00160 big_int (unsigned int x) { from_native_int(x); }
00161 big_int (signed long int x) { from_native_int(x); }
00162 big_int (unsigned long int x) { from_native_int(x); }
00163 big_int (bool x) { from_native_int(x); }
00164
00165 #ifdef ARAGELI_INT64_SUPPORT
00166
00167 big_int (signed __int64 x) { from_native_int(x); }
00168 big_int (unsigned __int64 x) { from_native_int(x); }
00169
00170 #endif
00171
00172 #ifdef ARAGELI_LONG_LONG_SUPPORT
00173
00174 big_int (signed long long x) { from_native_int(x); }
00175 big_int (unsigned long long x) { from_native_int(x); }
00176
00177 #endif
00178
00179 big_int (float x) { from_native_float(x); }
00180 big_int (double x) { from_native_float(x); }
00181 big_int (long double x) { from_native_float(x); }
00182
00184
00185
00188
00189 operator char () const
00190 { return to_native_int<char>(); }
00191
00192 operator signed char () const
00193 { return to_native_int<signed char>(); }
00194
00195 operator unsigned char () const
00196 { return to_native_int<unsigned char>(); }
00197
00198 operator signed short () const
00199 { return to_native_int<signed short>(); }
00200
00201 operator unsigned short () const
00202 { return to_native_int<unsigned short>(); }
00203
00204 operator signed int () const
00205 { return to_native_int<signed int>(); }
00206
00207 operator unsigned int () const
00208 { return to_native_int<unsigned int>(); }
00209
00210 operator signed long int () const
00211 { return to_native_int<signed long>(); }
00212
00213 operator unsigned long int () const
00214 { return to_native_int<unsigned long>(); }
00215
00216 operator bool () const { return !is_null(); }
00217
00218 #ifdef ARAGELI_INT64_SUPPORT
00219
00220 operator signed __int64 () const
00221 { return to_native_int<signed __int64>(); }
00222
00223 operator unsigned __int64 () const
00224 { return to_native_int<unsigned __int64>(); }
00225
00226 #endif
00227
00228 #ifdef ARAGELI_LONG_LONG_SUPPORT
00229
00230 operator signed long long () const
00231 { return to_native_int<signed long long>(); }
00232
00233 operator unsigned long long () const
00234 { return to_native_int<unsigned long long>(); }
00235
00236 #endif
00237
00238 operator float () const { return to_native_float<float>(); }
00239 operator double () const { return to_native_float<double>(); }
00240 operator long double () const { return to_native_float<long double>(); }
00241
00243
00244
00246 bool operator! () const { return is_null(); }
00247
00248 ~big_int () { free_number(); }
00249
00251
00258 big_int& operator= (const big_int & b);
00259
00260 big_int& operator= (const char* s)
00261 { return *this = big_int(s); }
00262
00263 big_int& operator= (char x) { from_native_int(x); return *this; }
00264 big_int& operator= (signed char x) { from_native_int(x); return *this; }
00265 big_int& operator= (unsigned char x) { from_native_int(x); return *this; }
00266 big_int& operator= (signed short x) { from_native_int(x); return *this; }
00267 big_int& operator= (unsigned short x) { from_native_int(x); return *this; }
00268 big_int& operator= (signed int x) { from_native_int(x); return *this; }
00269 big_int& operator= (unsigned int x) { from_native_int(x); return *this; }
00270 big_int& operator= (signed long int x) { from_native_int(x); return *this; }
00271 big_int& operator= (unsigned long int x) { from_native_int(x); return *this; }
00272 big_int& operator= (bool x) { from_native_int(x); return *this; }
00273
00274 #ifdef ARAGELI_INT64_SUPPORT
00275
00276 big_int& operator= (signed __int64 x) { from_native_int(x); return *this; }
00277 big_int& operator= (unsigned __int64 x) { from_native_int(x); return *this; }
00278
00279 #endif
00280
00281 #ifdef ARAGELI_LONG_LONG_SUPPORT
00282
00283 big_int& operator= (signed long long x) { from_native_int(x); return *this; }
00284 big_int& operator= (unsigned long long x) { from_native_int(x); return *this; }
00285
00286 #endif
00287
00288 big_int& operator= (float x) { from_native_float(x); return *this; }
00289 big_int& operator= (double x) { from_native_float(x); return *this; }
00290 big_int& operator= (long double x) { from_native_float(x); return *this; }
00291
00292 template <typename T>
00293 big_int& operator= (const rational<T>& x)
00294 { return *this = big_int(x); }
00295
00297
00298 std::size_t length () const;
00299
00301
00303 bool operator[] (std::size_t k) const;
00304
00306
00310 int sign () const { return number->sign; }
00311
00313 inline bool is_null () const;
00314
00316 inline bool is_unit () const;
00317
00319 inline bool is_opposite_unit () const;
00320
00322
00323 const big_int& operator+ () const { return *this; }
00324
00326 big_int operator- () const;
00327
00329
00330 big_int& operator++ () { return *this = *this + big_int(1); }
00331
00333
00334 big_int& operator-- () { return *this = *this - big_int(1); }
00335
00337
00338 big_int operator++ (int) { big_int t = *this; operator++(); return t; }
00339
00341
00342 big_int operator-- (int) { big_int t = *this; operator--(); return t; }
00343
00344 friend big_int operator+ (const big_int & b, const big_int & c);
00345 friend big_int operator- (const big_int & b, const big_int & c);
00346 friend big_int operator* (const big_int & b, const big_int & c);
00347 friend big_int operator/ (const big_int & b, const big_int & c);
00348 friend big_int operator% (const big_int & b, const big_int & c);
00349 friend big_int operator& (const big_int & b, const big_int & c);
00350 friend big_int operator| (const big_int & b, const big_int & c);
00351 friend big_int operator^ (const big_int & b, const big_int & c);
00352 friend std::ostream& operator<< (std::ostream& s, const big_int& x);
00353 friend std::istream& operator>> (std::istream& s, big_int& x);
00354 friend int cmp (const big_int & a, const big_int & b);
00355
00356 friend void _Internal::xdivide
00357 (big_int& a, const big_int& b, const big_int& c, big_int& res);
00358
00360
00363 static big_int random_with_length (std::size_t len)
00364 {
00365 return
00366 len ?
00367 random_with_length_or_less(len - 1) + (big_int(1) << (len - 1)) :
00368 big_int();
00369 }
00370
00372
00374 static big_int random_in_range (const big_int& max);
00375
00377
00380 static big_int random_with_length_or_less (std::size_t len);
00381
00382 friend big_int operator<< (const big_int& a, std::size_t n);
00383 friend big_int operator>> (const big_int& a, std::size_t n);
00384 friend big_int& operator>>= (big_int& a, std::size_t n);
00385
00386
00388 bool bit (std::size_t k) const { return operator[](k); }
00389
00391 bool is_even () const
00392 {
00393 if(!number->len)return true;
00394 return !(operator[](0));
00395 }
00396
00397
00398 #ifdef ARAGELI_DISABLE_PARTICULAR_COMPILER_WARNINGS
00399 #pragma warning (push)
00400 #pragma warning (disable : 4800)
00401 #endif
00402
00404 bool is_odd () const
00405 {
00406 if(!number->len)return false;
00407 return (operator[](0));
00408 }
00409
00410 #ifdef ARAGELI_DISABLE_PARTICULAR_COMPILER_WARNINGS
00411 #pragma warning (pop)
00412 #endif
00413
00414
00416 void swap (big_int& x) { std::swap(number, x.number); }
00417
00418 private:
00419
00420 friend class big_float;
00421
00422
00423
00424
00425 struct big_struct
00426 {
00427 int sign;
00428 digit *data;
00429 std::size_t len;
00430 int refs;
00431 } *number;
00432
00433
00434 void alloc_number (int new_sign, digit* new_mem, std::size_t new_len);
00435 void free_number ();
00436 void free_mem_and_alloc_number (int new_sign, digit* new_data, std::size_t new_len);
00437 void alloc_zero () { alloc_number(0, 0, 0); }
00438 void free_mem_and_alloc_zero ();
00439
00440 static digit* get_mem_for_data (std::size_t nitems);
00441 static void free_data (digit *p);
00442 static digit* realloc_data (digit* p, std::size_t newnitems);
00443
00444 static void copy_data
00445 (digit* dest, const digit* source, std::size_t newnitems);
00446
00447
00448 static digit* optimize (std::size_t& new_len, digit * p, std::size_t len);
00449
00450 template <typename T>
00451 void from_native_int (const T& x);
00452
00453 template <typename T>
00454 void from_native_float (const T& x);
00455
00456 template <typename T>
00457 T to_native_int () const;
00458
00459 template <typename T>
00460 T to_native_float () const;
00461
00462 template <typename T>
00463 T to_native_int_without_sign () const;
00464
00465 };
00466
00467
00469 inline std::size_t nbits (const big_int& x) { return x.length(); }
00470
00471
00473 std::ostream & operator<< (std::ostream & s, const big_int & x);
00474
00476 std::istream & operator>> (std::istream & s, big_int & x);
00477
00479
00485 int cmp (const big_int & a, const big_int & b);
00486
00487
00488 template <typename TT>
00489 inline int sign (const big_int& x)
00490 { return x.sign(); }
00491
00492
00495
00496 big_int operator+ (const big_int & b, const big_int & c);
00497 big_int operator- (const big_int & b, const big_int & c);
00498 big_int operator* (const big_int & b, const big_int & c);
00499 big_int operator/ (const big_int & b, const big_int & c);
00500 big_int operator% (const big_int & b, const big_int & c);
00501
00502 big_int operator<< (const big_int& a, std::size_t n);
00503 big_int operator>> (const big_int& a, std::size_t n);
00504
00505
00506 big_int operator| (const big_int& a, const big_int& b);
00507 big_int operator& (const big_int& a, const big_int& b);
00508 big_int operator^ (const big_int& a, const big_int& b);
00509
00511 template <typename T>
00512 inline big_int operator<< (const big_int& a, const T& b)
00513 { return a << std::size_t(b); }
00514
00516 template <typename T>
00517 inline big_int operator>> (const big_int& a, const T& b)
00518 { return a >> std::size_t(b); }
00519
00520 template <typename T>
00521 inline big_int& operator<<= (big_int& a, const T& b)
00522 { return a = a << b; }
00523
00524 inline big_int& operator>>= (big_int& a, std::size_t b)
00525 {
00526 if(a.number->len == 1)
00527 {
00528 if(a.number->refs > 1)
00529 {
00530 a.number->refs--;
00531 big_int::digit* newdata = big_int::get_mem_for_data(1);
00532 *newdata = *a.number->data;
00533 a.alloc_number(a.number->sign, newdata, 1);
00534 }
00535
00536 if(b >= _Internal::bits_per_digit || !(*a.number->data >>= b))
00537 a.free_mem_and_alloc_zero();
00538 }
00539 else
00540 a = a >> b;
00541
00542 return a;
00543 }
00544
00545 template <typename T>
00546 inline big_int& operator>>= (big_int& a, const T& b)
00547 { return a >>= std::size_t(b); }
00548
00549
00551
00552
00553
00555
00560 inline void divide (const big_int& a, const big_int& b, big_int& q, big_int& r)
00561 { return _Internal::xdivide(q, a, b, r); }
00562
00563
00564 #define _ARAGELI_big_int_CMP1(OPER) \
00565 inline bool operator OPER (const big_int& a, const big_int& b) \
00566 { return cmp(a, b) OPER 0; }
00567
00570
00571 _ARAGELI_big_int_CMP1(==)
00572 _ARAGELI_big_int_CMP1(!=)
00573 _ARAGELI_big_int_CMP1(<)
00574 _ARAGELI_big_int_CMP1(>)
00575 _ARAGELI_big_int_CMP1(<=)
00576 _ARAGELI_big_int_CMP1(>=)
00577
00579
00580
00581
00582
00583
00584
00585
00586
00587 #define _ARAGELI_big_int_COMBINED_OPER(OPER) \
00588 inline big_int& operator OPER##= (big_int& b, const big_int& c) \
00589 { return b = b OPER c; }
00590
00593
00594 _ARAGELI_big_int_COMBINED_OPER(+)
00595 _ARAGELI_big_int_COMBINED_OPER(-)
00596 _ARAGELI_big_int_COMBINED_OPER(*)
00597 _ARAGELI_big_int_COMBINED_OPER(/)
00598 _ARAGELI_big_int_COMBINED_OPER(%)
00599
00600
00601
00603
00604 #define _ARAGELI_big_int_MIXED_AOPER1(NATIVE, AOPER) \
00605 inline big_int& operator AOPER (big_int& b, NATIVE c) \
00606 { return b AOPER big_int(c); } \
00607 \
00608 inline NATIVE& operator AOPER (NATIVE& b, const big_int& c) \
00609 { return b AOPER (NATIVE)c; }
00610
00611 #define _ARAGELI_big_int_MIXED_BOPER1(NATIVE, BOPER) \
00612 inline big_int operator BOPER (NATIVE b, const big_int& c) \
00613 { return big_int(b) BOPER c; } \
00614 \
00615 inline big_int operator BOPER (const big_int& b, NATIVE c) \
00616 { return b BOPER big_int(c); }
00617
00618
00619 #define _ARAGELI_big_int_MIXED_COMARE1(NATIVE, BOPER) \
00620 inline bool operator BOPER (NATIVE b, const big_int& c) \
00621 { return big_int(b) BOPER c; } \
00622 \
00623 inline bool operator BOPER (const big_int& b, NATIVE c) \
00624 { return b BOPER big_int(c); }
00625
00626
00627 #define _ARAGELI_big_int_MIXED_COMPARE3(NATIVE) \
00628 _ARAGELI_big_int_MIXED_COMARE1(NATIVE, ==) \
00629 _ARAGELI_big_int_MIXED_COMARE1(NATIVE, !=) \
00630 _ARAGELI_big_int_MIXED_COMARE1(NATIVE, <=) \
00631 _ARAGELI_big_int_MIXED_COMARE1(NATIVE, >=) \
00632 _ARAGELI_big_int_MIXED_COMARE1(NATIVE, <) \
00633 _ARAGELI_big_int_MIXED_COMARE1(NATIVE, >)
00634
00635
00636 #ifdef ARAGELI_INT64_SUPPORT
00637
00638 #define _ARAGELI_big_int_MIXED_INT_AOPER2(AOPER) \
00639 _ARAGELI_big_int_MIXED_AOPER1(char, AOPER) \
00640 _ARAGELI_big_int_MIXED_AOPER1(signed char, AOPER) \
00641 _ARAGELI_big_int_MIXED_AOPER1(unsigned char, AOPER) \
00642 _ARAGELI_big_int_MIXED_AOPER1(signed short, AOPER) \
00643 _ARAGELI_big_int_MIXED_AOPER1(unsigned short, AOPER) \
00644 _ARAGELI_big_int_MIXED_AOPER1(signed int, AOPER) \
00645 _ARAGELI_big_int_MIXED_AOPER1(unsigned int, AOPER) \
00646 _ARAGELI_big_int_MIXED_AOPER1(signed long, AOPER) \
00647 _ARAGELI_big_int_MIXED_AOPER1(unsigned long, AOPER) \
00648 _ARAGELI_big_int_MIXED_AOPER1(signed __int64, AOPER) \
00649 _ARAGELI_big_int_MIXED_AOPER1(unsigned __int64, AOPER) \
00650 _ARAGELI_big_int_MIXED_AOPER1(bool, AOPER)
00651
00652 #define _ARAGELI_big_int_MIXED_INT_BOPER2(BOPER) \
00653 _ARAGELI_big_int_MIXED_BOPER1(char, BOPER) \
00654 _ARAGELI_big_int_MIXED_BOPER1(signed char, BOPER) \
00655 _ARAGELI_big_int_MIXED_BOPER1(unsigned char, BOPER) \
00656 _ARAGELI_big_int_MIXED_BOPER1(signed short, BOPER) \
00657 _ARAGELI_big_int_MIXED_BOPER1(unsigned short, BOPER) \
00658 _ARAGELI_big_int_MIXED_BOPER1(signed int, BOPER) \
00659 _ARAGELI_big_int_MIXED_BOPER1(unsigned int, BOPER) \
00660 _ARAGELI_big_int_MIXED_BOPER1(signed long, BOPER) \
00661 _ARAGELI_big_int_MIXED_BOPER1(unsigned long, BOPER) \
00662 _ARAGELI_big_int_MIXED_BOPER1(signed __int64, BOPER) \
00663 _ARAGELI_big_int_MIXED_BOPER1(unsigned __int64, BOPER) \
00664 _ARAGELI_big_int_MIXED_BOPER1(bool, BOPER)
00665
00666 #else
00667
00668 #define _ARAGELI_big_int_MIXED_INT_AOPER2(AOPER) \
00669 _ARAGELI_big_int_MIXED_AOPER1(char, AOPER) \
00670 _ARAGELI_big_int_MIXED_AOPER1(signed char, AOPER) \
00671 _ARAGELI_big_int_MIXED_AOPER1(unsigned char, AOPER) \
00672 _ARAGELI_big_int_MIXED_AOPER1(signed short, AOPER) \
00673 _ARAGELI_big_int_MIXED_AOPER1(unsigned short, AOPER) \
00674 _ARAGELI_big_int_MIXED_AOPER1(signed int, AOPER) \
00675 _ARAGELI_big_int_MIXED_AOPER1(unsigned int, AOPER) \
00676 _ARAGELI_big_int_MIXED_AOPER1(signed long, AOPER) \
00677 _ARAGELI_big_int_MIXED_AOPER1(unsigned long, AOPER) \
00678 _ARAGELI_big_int_MIXED_AOPER1(bool, AOPER)
00679
00680 #define _ARAGELI_big_int_MIXED_INT_BOPER2(BOPER) \
00681 _ARAGELI_big_int_MIXED_BOPER1(char, BOPER) \
00682 _ARAGELI_big_int_MIXED_BOPER1(signed char, BOPER) \
00683 _ARAGELI_big_int_MIXED_BOPER1(unsigned char, BOPER) \
00684 _ARAGELI_big_int_MIXED_BOPER1(signed short, BOPER) \
00685 _ARAGELI_big_int_MIXED_BOPER1(unsigned short, BOPER) \
00686 _ARAGELI_big_int_MIXED_BOPER1(signed int, BOPER) \
00687 _ARAGELI_big_int_MIXED_BOPER1(unsigned int, BOPER) \
00688 _ARAGELI_big_int_MIXED_BOPER1(signed long, BOPER) \
00689 _ARAGELI_big_int_MIXED_BOPER1(unsigned long, BOPER) \
00690 _ARAGELI_big_int_MIXED_BOPER1(bool, BOPER)
00691
00692 #endif
00693
00694 #define _ARAGELI_big_int_MIXED_FLOAT_AOPER2(AOPER) \
00695 _ARAGELI_big_int_MIXED_AOPER1(float, AOPER) \
00696 _ARAGELI_big_int_MIXED_AOPER1(double, AOPER) \
00697 _ARAGELI_big_int_MIXED_AOPER1(long double, AOPER)
00698
00699 #define _ARAGELI_big_int_MIXED_FLOAT_BOPER2(BOPER) \
00700 _ARAGELI_big_int_MIXED_BOPER1(float, BOPER) \
00701 _ARAGELI_big_int_MIXED_BOPER1(double, BOPER) \
00702 _ARAGELI_big_int_MIXED_BOPER1(long double, BOPER)
00703
00704
00705 #ifdef ARAGELI_DISABLE_PARTICULAR_COMPILER_WARNINGS
00706 #pragma warning (push)
00707 #pragma warning (disable : 4804)
00708 #pragma warning (disable : 4800)
00709 #endif
00710
00711
00712 _ARAGELI_big_int_MIXED_INT_AOPER2(+=)
00713 _ARAGELI_big_int_MIXED_INT_AOPER2(-=)
00714 _ARAGELI_big_int_MIXED_INT_AOPER2(*=)
00715 _ARAGELI_big_int_MIXED_INT_AOPER2(/=)
00716
00717 _ARAGELI_big_int_MIXED_FLOAT_AOPER2(+=)
00718 _ARAGELI_big_int_MIXED_FLOAT_AOPER2(-=)
00719 _ARAGELI_big_int_MIXED_FLOAT_AOPER2(*=)
00720 _ARAGELI_big_int_MIXED_FLOAT_AOPER2(/=)
00721
00722 _ARAGELI_big_int_MIXED_INT_AOPER2(%=)
00723
00724
00725
00726
00727 #ifdef ARAGELI_DISABLE_PARTICULAR_COMPILER_WARNINGS
00728 #pragma warning (pop)
00729 #endif
00730
00731 _ARAGELI_big_int_MIXED_INT_BOPER2(+)
00732 _ARAGELI_big_int_MIXED_INT_BOPER2(-)
00733 _ARAGELI_big_int_MIXED_INT_BOPER2(*)
00734 _ARAGELI_big_int_MIXED_INT_BOPER2(/)
00735
00736 _ARAGELI_big_int_MIXED_FLOAT_BOPER2(+)
00737 _ARAGELI_big_int_MIXED_FLOAT_BOPER2(-)
00738 _ARAGELI_big_int_MIXED_FLOAT_BOPER2(*)
00739 _ARAGELI_big_int_MIXED_FLOAT_BOPER2(/)
00740
00741 _ARAGELI_big_int_MIXED_INT_BOPER2(%)
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 _ARAGELI_big_int_MIXED_COMPARE3(char)
00760 _ARAGELI_big_int_MIXED_COMPARE3(signed char)
00761 _ARAGELI_big_int_MIXED_COMPARE3(unsigned char)
00762 _ARAGELI_big_int_MIXED_COMPARE3(signed short)
00763 _ARAGELI_big_int_MIXED_COMPARE3(unsigned short)
00764 _ARAGELI_big_int_MIXED_COMPARE3(signed int)
00765 _ARAGELI_big_int_MIXED_COMPARE3(unsigned int)
00766 _ARAGELI_big_int_MIXED_COMPARE3(signed long)
00767 _ARAGELI_big_int_MIXED_COMPARE3(unsigned long)
00768 _ARAGELI_big_int_MIXED_COMPARE3(bool)
00769
00770 _ARAGELI_big_int_MIXED_COMPARE3(float)
00771 _ARAGELI_big_int_MIXED_COMPARE3(double)
00772 _ARAGELI_big_int_MIXED_COMPARE3(long double)
00773
00774
00775 #ifdef ARAGELI_INT64_SUPPORT
00776
00777 _ARAGELI_big_int_MIXED_COMPARE3(signed __int64)
00778 _ARAGELI_big_int_MIXED_COMPARE3(unsigned __int64)
00779
00780 #endif
00781
00782
00783 inline bool big_int::is_null () const { return number->sign == 0; }
00784
00785 inline bool big_int::is_unit () const
00786 { return number->len == 1 && number->sign == +1 && *number->data == 1; }
00787
00788 inline bool big_int::is_opposite_unit () const
00789 { return number->len == 1 && number->sign == -1 && *number->data == 1; }
00790
00791 inline bool is_null (const big_int& x)
00792 { return x.is_null(); }
00793
00794 inline bool is_unit (const big_int& x)
00795 { return x.is_unit(); }
00796
00797 inline bool is_opposite_unit (const big_int& x)
00798 { return x.is_opposite_unit(); }
00799
00800 inline bool is_positive (const big_int& x)
00801 { return x.sign() > 0; }
00802
00803 inline bool is_negative (const big_int& x)
00804 { return x.sign() < 0; }
00805
00806 inline bool is_even (const big_int& x)
00807 { return x.is_even(); }
00808
00809
00810 inline bool is_odd (const big_int& x)
00811 { return x.is_odd(); }
00812
00813
00815
00816
00817
00818 template <typename T>
00819 T intsqrt (const T& a);
00821
00822
00823 inline big_int sqrt (const big_int& a)
00824 { return intsqrt(a); }
00825
00827 inline big_int abs (const big_int& x)
00828 {
00829 if(x.sign() < 0)return -x;
00830 else return x;
00831 }
00832
00834
00835 inline big_int pow (const big_int& x, int p)
00836 { return power(x, p); }
00837
00839
00840 inline big_int pow (const big_int& x, const big_int& p)
00841 { return power(x, p); }
00842
00844 inline big_int log2 (const big_int& x) { return x.length() - 1; }
00845
00846 }
00847
00848
00849 namespace std
00850 {
00851
00852 inline Arageli::big_int sqrt (const Arageli::big_int& a)
00853 { return Arageli::sqrt(a); }
00854
00856 inline Arageli::big_int abs (const Arageli::big_int& x)
00857 { return Arageli::abs(x); }
00858
00860
00861 inline Arageli::big_int pow (const Arageli::big_int& x, int p)
00862 { return Arageli::pow(x, p); }
00863
00865
00866 inline Arageli::big_int pow
00867 (const Arageli::big_int& x, const Arageli::big_int& p)
00868 { return Arageli::pow(x, p); }
00869
00871 template <> class numeric_limits<Arageli::big_int>
00872 {
00873 typedef Arageli::big_int TTT;
00874
00875 public:
00876
00877 static const bool is_specialized = true;
00878
00879 static TTT min () throw() { return TTT(); }
00880 static TTT max () throw() { return TTT(); }
00881 static const int digits = 0;
00882 static const int digits10 = 0;
00883 static const bool is_signed = true;
00884 static const bool is_integer = true;
00885 static const bool is_exact = true;
00886 static const int radix = 2;
00887 static TTT epsilon () throw() { return TTT(); }
00888 static TTT round_error () throw() { return TTT(); }
00889 static const int min_exponent = 0;
00890 static const int min_exponent10 = 0;
00891 static const int max_exponent = 0;
00892 static const int max_exponent10 = 0;
00893 static const bool has_infinity = false;
00894 static const bool has_quiet_NaN = false;
00895 static const bool has_signaling_NaN = false;
00896 static const float_denorm_style has_denorm = denorm_absent;
00897 static const bool has_denorm_loss = false;
00898 static TTT infinity () throw() { return TTT(); }
00899 static TTT quiet_NaN () throw() { return TTT(); }
00900 static TTT signaling_NaN () throw() { return TTT(); }
00901 static TTT denorm_min () throw() { return TTT(); }
00902 static const bool is_iec559 = false;
00903 static const bool is_bounded = false;
00904 static const bool is_modulo = false;
00905 static const bool traps = true;
00906 static const bool tinyness_before = false;
00907 static const float_round_style round = round_toward_zero;
00908 };
00909
00910
00912 inline void swap (Arageli::big_int& a, Arageli::big_int& b)
00913 { a.swap(b); }
00914
00915
00916 }
00917
00918
00919 namespace Arageli
00920 {
00921
00922 #if 0
00923
00925 template <typename T2>
00926 struct type_pair_traits<big_int, T2>
00927 {
00928 static const bool is_specialized = type_traits<T2>::is_specialized;
00929 static const bool is_convertible = type_traits<T2>::is_number;
00930 static const bool is_safe_convertible = false;
00931 static const bool is_assignable = is_convertible;
00932 static const bool is_safe_assignable = is_safe_convertible;
00933 static const bool is_initializable = is_convertible;
00934 static const bool is_safe_initializable = is_safe_convertible;
00935 };
00936
00937
00939 template <typename T1>
00940 struct type_pair_traits<T1, big_int>
00941 {
00942 static const bool is_specialized = type_traits<T1>::is_specialized;
00943 static const bool is_convertible = type_traits<T1>::is_number;
00944
00945 static const bool is_safe_convertible =
00946 type_traits<T1>::is_integer_number &&
00947 std::numeric_limits<T1>::is_specialized &&
00948 std::numeric_limits<T1>::is_bounded;
00949
00950 static const bool is_assignable = is_convertible;
00951 static const bool is_safe_assignable = is_safe_convertible;
00952 static const bool is_initializable = is_convertible;
00953 static const bool is_safe_initializable = is_safe_convertible;
00954 };
00955
00956
00958 template <>
00959 struct type_pair_traits<big_int, big_int> :
00960 public type_pair_traits_for_the_same<big_int> {};
00961
00962 #endif
00963
00964 }
00965
00966
00967 #ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
00968 #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_BIG_INT
00969 #include "big_int.cpp"
00970 #undef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_BIG_INT
00971 #endif
00972
00973
00974 #endif