big_int.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     big_int.hpp.
00004 
00005     This file is a part of the Arageli library.
00006     
00007     Big Integer Numbers implementation.
00008 
00009     This module implements a class big_int for representing
00010     Big Integer Numbers, i.e. `arbitrary precision' integers.
00011 
00012     WARNIG. This file has no complate implementation.
00013 
00014     Copyright (C) Nikolai Yu. Zolotykh, 1999 -- 2005
00015     University of Nizhni Novgorod, Russia
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     // a = b / c; res = b % c
00060     void xdivide (big_int& a, const big_int& b, const big_int& c, big_int& res);
00061 }
00062 
00063 
00064 // The following declaration is needed only for one additional definition
00065 // in big_int class.  That definition is created for GCC compatibility only.
00066 // See template <typename TT2> big_int::big_int (const rational<big_int>& x).
00067 
00068 // template <typename T> class rational;    // see rational.hpp
00069 
00070 
00072 class big_int
00073 {
00074     // A type for one elementary digit.
00075     // Number consist of sequence of objects of this type.
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     // WARNING!  A message storage is duplicated in the incorrec_string class.
00100     // Realy two verstions of this storage are presented in the class.
00101     // TODO: Resolve it.
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; // see big_float.hpp source file
00421 
00422     // the following type is used inside the big_int unit and implements
00423     // the storage for a Big Integer Number
00424 
00425     struct big_struct
00426     {
00427         int sign;       // the sign: 0, 1 or -1
00428         digit *data;    // the storage for digits
00429         std::size_t len;        // the number of digits
00430         int refs;       // the number of points to this number
00431     } *number;
00432 
00433     // number allocation routines
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     // Erases leading zeros.
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 // WARNING.  The following operators have not implemented yet.
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 /*   Combined operators    */
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 //_ARAGELI_big_int_COMBINED_OPER(>>)
00600 //_ARAGELI_big_int_COMBINED_OPER(<<)
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; }   /* WARNING */
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 //_ARAGELI_big_int_MIXED_INT_AOPER2(<<=)
00725 //_ARAGELI_big_int_MIXED_INT_AOPER2(>>=)
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 //_ARAGELI_big_int_MIXED_INT_BOPER2(<<)
00743 //_ARAGELI_big_int_MIXED_INT_BOPER2(>>)
00744 
00745 //_ARAGELI_big_int_MIXED_INT_BOPER2(==)
00746 //_ARAGELI_big_int_MIXED_INT_BOPER2(!=)
00747 //_ARAGELI_big_int_MIXED_INT_BOPER2(<)
00748 //_ARAGELI_big_int_MIXED_INT_BOPER2(>)
00749 //_ARAGELI_big_int_MIXED_INT_BOPER2(<=)
00750 //_ARAGELI_big_int_MIXED_INT_BOPER2(>=)
00751 
00752 //_ARAGELI_big_int_MIXED_FLOAT_BOPER2(==)
00753 //_ARAGELI_big_int_MIXED_FLOAT_BOPER2(!=)
00754 //_ARAGELI_big_int_MIXED_FLOAT_BOPER2(<)
00755 //_ARAGELI_big_int_MIXED_FLOAT_BOPER2(>)
00756 //_ARAGELI_big_int_MIXED_FLOAT_BOPER2(<=)
00757 //_ARAGELI_big_int_MIXED_FLOAT_BOPER2(>=)
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 // WARNING! This function prototype is placed here because header dependences.
00816 // WARNING! The problem appears only if ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE macro is undefined.
00817 // TODO: Resolve this problem and delete.
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

Generated on Thu Aug 31 17:38:04 2006 for Arageli by  doxygen 1.4.7