00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef __ARAGELI_bigar_hpp__
00016 #define __ARAGELI_bigar_hpp__
00017
00018 #include "config.hpp"
00019
00020 #include <cstddef>
00021 #include <cstdlib>
00022 #include <limits>
00023
00024 #include "std_import.hpp"
00025
00026
00027 namespace Arageli { namespace _Internal
00028 {
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #if defined(_MSC_VER) && defined (_WIN32) || 0 && defined(__BORLANDC__) && defined(__WIN32__)
00051
00052
00053
00054
00055
00056 typedef unsigned long digit;
00057 typedef unsigned __int64 doubledigit;
00058 typedef unsigned __int64 extendeddigit;
00059 typedef unsigned short int bit;
00060 const digit max_digit = 0xFFFFFFFF;
00061 const extendeddigit BASE = 0x100000000l;
00062 const int bits_per_digit = 32;
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 #elif defined ARAGELI_LONG_LONG_SUPPORT
00073 typedef unsigned long digit;
00074 typedef unsigned long long doubledigit;
00075 typedef unsigned long long extendeddigit;
00076 typedef unsigned short int bit;
00077 const digit max_digit = 0xFFFFFFFF;
00078 const extendeddigit BASE = 0x100000000l;
00079 const int bits_per_digit = 32;
00080 #else
00081
00082
00083
00084
00085 typedef unsigned short digit;
00086 typedef unsigned long doubledigit;
00087 typedef unsigned long extendeddigit;
00088 typedef unsigned short bit;
00089 const digit max_digit = 0xFFFF;
00090 const extendeddigit BASE = 0x10000l;
00091 const int bits_per_digit = 16;
00092 #endif
00093
00094
00095 std::size_t do_big_int_to_bdn (digit* a, digit* b, std::size_t n, digit bdn_radix);
00096 std::size_t do_bdn_to_big_int (digit* a, digit* b, std::size_t n, digit bdn_radix);
00097 std::size_t do_add (digit* p1, const digit* p2, std::size_t m, std::size_t n);
00098 int do_sub (digit* p1, const digit* p2, std::size_t m, std::size_t n);
00099 std::size_t do_optimize (const digit* a, std::size_t n);
00100 std::size_t do_mult (const digit* u, const digit* v, digit* w, std::size_t m, std::size_t n);
00101
00102 digit do_divide_by_digit (const digit* a, digit* p, std::size_t n, digit d);
00103 std::size_t do_divide (digit* u, digit* v, digit* q, std::size_t m, std::size_t n);
00104
00105 }
00106
00107 #if 0
00108
00109 namespace Bigar
00110 {
00111
00112 template <typename D> struct doubledigit;
00113 template <typename D> struct extendeddigit;
00114 template <typename D> struct bits_per_digit;
00115 template <typename D> struct max_digit;
00116 template <typename D> struct base;
00117
00118
00119 template <> struct doubledigit<unsigned long>
00120 { typedef unsigned __int64 type; };
00121
00122 template <> struct extendeddigit<unsigned long>
00123 { typedef unsigned __int64 type; };
00124
00125 template <> struct bits_per_digit<unsigned long>
00126 {
00127 static const unsigned int
00128 value = std::numeric_limits<unsigned long>::digits;
00129 };
00130
00131 template <> struct max_digit<unsigned long>
00132 {
00133 static const unsigned long value;
00134 };
00135
00136 const unsigned long max_digit<unsigned long>::value
00137 = std::numeric_limits<unsigned long>::max();
00138
00139 template <> struct base<unsigned long>
00140 {
00141 private:
00142 typedef extendeddigit<unsigned long>::type exdig;
00143 public:
00144 static const exdig
00145 value;
00146 };
00147
00148 const extendeddigit<unsigned long>::type
00149 base<unsigned long>::value = static_cast<exdig>(max_digit<unsigned long>::value) + 1;
00150
00151 typedef unsigned char bit;
00152
00153 template <typename D> struct digit_info
00154 {
00155 typedef typename Bigar::doubledigit<D>::type doubledigit;
00156 typedef typename Bigar::extendeddigit<D>::type extendeddigit;
00157 static const unsigned int bits_per_digit = Bigar::bits_per_digit<D>::value;
00158 static const D max_digit = Bigar::max_digit<D>::value;
00159 static const extendeddigit base = Bigar::base<D>::value;
00160 };
00161
00162
00163 template <typename In, typename Out>
00164 typename std::iterator_traits<Out>::difference_type
00165 addseq
00166 (
00167 Out res,
00168 In in,
00169 typename std::iterator_traits<Out>::difference_type size_res,
00170 typename std::iterator_traits<Out>::difference_type size_in
00171 );
00172
00173 template <typename In, typename Out>
00174 typename std::iterator_traits<Out>::difference_type
00175 addseq
00176 (
00177 Out res,
00178 In in,
00179 typename std::iterator_traits<Out>::difference_type size_res,
00180 typename std::iterator_traits<Out>::difference_type size_in
00181 )
00182 {
00183 ARAGELI_ASSERT_1(size_res >= size_in);
00184
00185 typedef std::iterator_traits<Out> Out_traits;
00186 typedef typename Out_traits::difference_type pos_type;
00187 typedef digit_info<typename Out_traits::value_type> digit_info;
00188
00189
00190
00191
00192 ARAGELI_ASSERT_1(m >= n);
00193
00194 bit carry = 0;
00195
00196
00197
00198 for(pos_type i = 0; i < n; i++)
00199 {
00200 typename digit_info::doubledigit
00201 tmp = static_cast<typename digit_info::doubledigit>(p1[i])
00202 + p2[i] + carry;
00203
00204 res[i] = digit(tmp % digit_info::base);
00205 carry = digit(tmp / digit_info::base);
00206 }
00207
00208
00209
00210 for(pos_type i = n; i < m; i++)
00211 {
00212 doubledigit tmp = doubledigit(p1[i]) + carry;
00213 p1[i] = digit(tmp % BASE);
00214 carry = digit(tmp / BASE);
00215 if(carry == 0) break;
00216 }
00217
00218 if(carry)
00219 {
00220 p1[m] = 1;
00221 return m + 1;
00222 }
00223 else return m;
00224 }
00225
00226
00227
00228 }
00229
00230 #endif
00231
00232
00233 }
00234
00235 #endif