00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "config.hpp"
00019
00020 #include <cstddef>
00021 #include <cmath>
00022
00023 #include "big_int.hpp"
00024 #include "big_const.hpp"
00025 #include "powerest.hpp"
00026
00027 #define SPARE 0xA // WARNING! Macro!!!
00028
00029 namespace Arageli
00030 {
00031
00032
00033 big_int entier ( const big_int &de )
00034 {
00035 if ( !de.length() )
00036 return 0;
00037
00038 std::size_t counter = 0;
00039 std::size_t factor = 1;
00040 std::size_t spare_bits;
00041 std::size_t len = de.length ();
00042 big_int L;
00043 int fl = 1;
00044
00045 while ( fl )
00046 {
00047 L = log2_10_u ( len + SPARE * factor ) * de;
00048
00049
00050 spare_bits = SPARE * factor;
00051 while ( counter < spare_bits )
00052 {
00053 if ( ! L[ counter + len ] )
00054 {
00055 fl = 0;
00056 break;
00057 }
00058 counter++;
00059 }
00060 if ( counter == spare_bits )
00061 {
00062 factor++;
00063 counter = 0;
00064 }
00065 }
00066 if ( de > 0 )
00067 return ( L >> ( len + SPARE * factor + 1 ) ) + 3 * de;
00068 return ( L >> ( len + SPARE * factor + 1 ) ) + 3 * de - 1;
00069 }
00070
00071 big_int frac ( const big_int &de, std::size_t kbits)
00072 {
00073 std::size_t n = ( kbits - 1 ) / 3 + 2;
00074 kbits += n + 4 ;
00075 big_int L;
00076 std::size_t len = de.length ( );
00077
00078
00079 do
00080 {
00081 L = log2_10_u ( len + kbits ) * de;
00082 L = - (( L >> ( len + kbits + 1 ) ) << ( len + kbits + 1)) + L;
00083 len += SPARE;
00084
00085 }
00086 while ( ( ( L + pow2<big_int> ( kbits + 1 ) ) >> ( len - SPARE + kbits + 1) ) == 1 );
00087 if ( L < 0 ) L = L + pow2<big_int> ( len + kbits + 1 - SPARE ) - 2;
00088 L = L >> len - SPARE + 4;
00089
00090
00091 kbits -= 3 ;
00092 std::size_t counter = 1;
00093 big_int s;
00094 big_int a = pow2<big_int> ( kbits );
00095 len = (kbits << 1) + 1;
00096 L = L * ln2_u ( kbits );
00097
00098
00099 s = s + a;
00100 while ( counter < n )
00101 {
00102 a = ( ( a * L ) / counter ) >> len;
00103 s = s + a;
00104 counter++;
00105 }
00106 return ( s >> n + 1 ) + 1;
00107 }
00108
00110 std::size_t lg10 ( const big_int &b )
00111 {
00112 std::size_t res = 0;
00113 big_int temp ( b );
00114
00115 while ( ( temp = temp / 10 ) != 0 )
00116 res++;
00117
00118 return res;
00119 }
00121 std::size_t lg10 ( std::size_t b )
00122 {
00123 std::size_t res = 0;
00124 std::size_t temp ( b );
00125
00126 while ( ( temp /= 10 ) != 0 )
00127 res++;
00128
00129 return res;
00130 }
00131
00133 big_int power_of_ten ( std::size_t pow )
00134 {
00135 big_int res ( 1 );
00136
00137 while ( pow-- )
00138 res = res * 10;
00139 return res;
00140 }
00141
00142
00143 big_int entier_1 ( const big_int &be )
00144 {
00145 if ( be == 0 ) return 0;
00146
00147 int s = 0;
00148 std::size_t kbits ( be.length () + SPARE );
00149 big_int L ( be );
00150 if ( L < 0 )
00151 {
00152 L = -L;
00153 s = - 1;
00154 }
00155 big_int three ( 3 );
00156 do
00157 {
00158 L = ( L << ( kbits * 2 + 2) ) / (( three << kbits )+ log2_10_o ( kbits - 1 )) ;
00159 kbits += SPARE;
00160 } while ( ( ( L + 2 ) >> kbits + 1 ) != ( L >> kbits + 1 ) );
00161
00162 if ( s ) return - ( L >> kbits - SPARE + 2 ) - 1;
00163 return L >> kbits - SPARE + 2;
00164 }
00165
00167 big_int frac_1 ( const big_int &de, std::size_t kbits)
00168 {
00169 if ( de == 0 ) return pow2<big_int> ( kbits ) ;
00170
00171 std::size_t prec = kbits + 8;
00172 std::size_t l = de.length() + prec + 1;
00173 big_int L;
00174
00175 do
00176 {
00177 L = de * lg_2_u( l );
00178 L = L - ( (L >> l + 1) << l + 1);
00179 if ( L < 0 ) L = L + pow2<big_int> ( l + 1 ) - 2 ;
00180 l += SPARE;
00181 } while ( (L + pow2<big_int> ( de.length() + 1 ) ).length() > l);
00182 L = L >> ( l - SPARE - prec );
00183
00184
00185
00186 L = L * ( ln1_25_u ( prec ) + 3 * ln2_u ( prec ) );
00187
00188
00189
00190
00191
00192 std::size_t n = ( kbits + 1 ) / 3 + 2;
00193 n = (n < 20 ) ? 20 : n;
00194 std::size_t pos = log ( (long double)n ) / log ( 2.0l ) + 2;
00195 std::size_t counter = 1;
00196 big_int s;
00197 big_int a = pow2<big_int> ( kbits + pos );
00198 std::size_t len = 2 * prec + 2;
00199
00200 s = s + a;
00201 while ( counter < n )
00202 {
00203 a = ( (a * L) / counter) >> len ;
00204 s = s + a;
00205 counter++;
00206 }
00207
00208 return ( s >> pos ) + 1;
00209 }
00210
00211
00212
00213
00214
00215
00216
00217 void do_bin_convert ( const big_int &dm, const big_int &de, std::size_t p, big_int &bm, big_int &be )
00218 {
00219 if ( dm == 0 )
00220 {
00221 bm = be = 0;
00222 return;
00223 }
00224
00225 be = entier ( de ) + log2 ( dm ) - p;
00226
00227
00228 bm = frac ( de, p );
00229
00230 bm = bm * dm / pow2<big_int> ( log2(dm));
00231
00232
00233 if ( bm.length () - p )
00234 {
00235 be = be + 1;
00236 bm = bm >> 1;
00237 }
00238 }
00239
00240
00241
00242
00243
00244
00245
00246 std::size_t do_dec_convert ( big_int &dm, big_int &de, std::size_t p, const big_int & bm, const big_int & be )
00247 {
00248
00249
00250
00251 de = entier_1 ( be ) + lg10 ( bm ) - p;
00252
00253
00254 std::size_t bp = std::size_t (( double )( p + 1 ) * ( log ( 10.0l ) / log ( 2.0l ) ) + 4.0);
00255 dm = frac_1 ( be, bp );
00256
00257
00258
00259
00260
00261 dm = ( bm * dm * power_of_ten ( p + 1 ) >> bp )/ power_of_ten ( lg10 (bm) ) ;
00262
00263 dm = ( dm + 5 * dm.sign () ) / 10;
00264
00265
00266 if ( ! (lg10 ( dm ) - p - 1) )
00267 {
00268 de = de + 1;
00269 dm = (dm + 5 * dm.sign ()) / 10;
00270
00271 }
00272 if ( ! ( lg10 ( dm ) - p + 1 ) )
00273 {
00274 de = de - 1;
00275 dm = dm * 10;
00276 }
00277
00278 return lg10 ( de );
00279 }
00280
00281 }
00282
00283