00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "config.hpp"
00016
00017 #include <cstddef>
00018 #include <cmath>
00019
00020 #include "big_const.hpp"
00021
00022
00023 #pragma warning(disable : 4244) // here: conversion from long double to size_t,
00024
00025
00026 namespace Arageli
00027 {
00028
00029
00030 big_int ln1_25 ( std::size_t kbits )
00031 {
00032 std::size_t n = (int) (kbits - 4) / 4 + 1;
00033 if ( n <= 1) n++;
00034 std::size_t pos = log ( (long double)n ) / log ( 2.0l ) + 3;
00035
00036 big_int s(0);
00037 big_int a;
00038 unsigned counter = 1;
00039
00040 kbits +=1 ;
00041 n <<= 1;
00042 while (counter <= n)
00043 {
00044 a = pow2<big_int>(kbits + pos - (counter<<1))/counter;
00045 counter++;
00046 s = s + a;
00047 a = pow2<big_int>(kbits + pos - (counter<<1))/counter;
00048 counter++;
00049 s = s - a - 1;
00050 }
00051 return (s >> pos ) + 1;
00052 }
00053
00054 big_int ln1_25_o(std::size_t kbits)
00055 {
00056 return ln1_25 ( kbits ) + 1;
00057 }
00058
00059 big_int ln1_25_u ( std::size_t kbits )
00060 {
00061 return ln1_25 ( kbits ) - 1;
00062 }
00063
00064
00065 big_int ln2 ( std::size_t kbits )
00066 {
00067 std::size_t n = ( kbits - 1 )/ 3 + 1;
00068 std::size_t pos = log ( (long double)n ) / log ( 2.0l ) + 2;
00069 big_int s(0);
00070 big_int a,b;
00071 unsigned counter = 1;
00072
00073 kbits++;
00074 a = pow2<big_int>( kbits + pos ) / 3;
00075 s = s + a;
00076 while ( counter < n )
00077 {
00078
00079 a = (a * ((counter << 1) - 1))/(((counter << 1) + 1) * 9);
00080 s = s + a;
00081 counter++;
00082 }
00083
00084 return (s >> pos - 1) + 1 ;
00085 }
00086
00087 big_int ln2_u ( std::size_t kbits )
00088 {
00089 return ln2 ( kbits ) - 1;
00090 }
00091
00092 big_int ln2_o(std::size_t kbits)
00093 {
00094 return ln2 ( kbits ) + 1;
00095 }
00096
00097
00098
00099 big_int log2_10 ( std::size_t nbits )
00100 {
00101 big_int numerator = ln1_25_u ( nbits + 3 );
00102 big_int denumerator = ln2_o ( nbits + 3 );
00103 return ( numerator << ( nbits + 1 ))/ denumerator + 1;
00104 }
00105 big_int log2_10_o ( std::size_t nbits )
00106 {
00107 return log2_10 ( nbits ) + 1;
00108 }
00109
00110 big_int log2_10_u ( std::size_t nbits )
00111 {
00112 return log2_10 ( nbits ) + 1;
00113 }
00114
00115
00116
00117 big_int lg_2_o ( std::size_t nbits )
00118 {
00119 return lg_2 ( nbits ) + 1;
00120 }
00121
00122 big_int lg_2_u ( std::size_t nbits )
00123 {
00124 return lg_2 ( nbits ) - 1;
00125 }
00126
00127 big_int lg_2 ( std::size_t nbits )
00128 {
00129 big_int numerator = ln2_u ( nbits + 3 );
00130 big_int denumerator = 3 * ( numerator + 2 ) + ln1_25_o ( nbits + 3 );
00131 return ( numerator << ( nbits + 1 ))/ denumerator + 1;
00132 }
00133
00134
00135
00136
00137
00138 big_int exp_u (big_int arg, std::size_t kbits, int factor)
00139 {
00140 return exp ( arg, kbits, factor) - 1;
00141 }
00142
00143
00144
00145 big_int exp_o (big_int arg, std::size_t kbits, int factor)
00146 {
00147 return exp ( arg, kbits, factor) + 1;
00148 }
00149
00150
00151
00152 big_int exp (big_int arg, std::size_t kbits, int factor)
00153 {
00154
00155
00156 std::size_t n = int ( kbits - 2 ) / 3 + 2;
00157 if ( n <= 19 ) n = 20;
00158 std::size_t pos = log ( (long double)n ) / log ( 2.0l ) + 2;
00159 std::size_t counter = 1;
00160 big_int s;
00161
00162 kbits++;
00163 big_int a = pow2<big_int> ( kbits + pos );
00164 std::size_t len = arg.length ( ) + factor;
00165
00166 s = s + a;
00167 while ( counter < n )
00168 {
00169 a = ( (a * arg) / counter) >> len ;
00170 s = s + a;
00171 counter++;
00172 }
00173 return ( s >> pos ) + 1 ;
00174 }
00175
00176
00177
00178
00179 big_int exp_2_u ( big_int arg, std::size_t kbits, int factor)
00180 {
00181 return exp_2 ( arg, kbits, factor) -1;
00182 }
00183
00184 big_int exp_2_o ( big_int arg, std::size_t kbits, int factor)
00185 {
00186 return exp_2 ( arg, kbits, factor) + 1;
00187 }
00188
00189 big_int exp_2 ( big_int arg, std::size_t kbits, int factor)
00190 {
00191 std::size_t n = ( kbits - 1 ) / 3 + 2;
00192 if ( n <= 19 ) n = 20;
00193 kbits++;
00194 std::size_t counter = 1;
00195 big_int s;
00196 big_int a = pow2<big_int> ( kbits + n);
00197 std::size_t len = kbits + n + arg.length ( ) + factor;
00198 arg = arg * ln2_u ( kbits + n );
00199
00200 s = s + a;
00201 while ( counter < n )
00202 {
00203 a = ( ( a * arg ) / counter ) >> len ;
00204 s = s + a;
00205 counter++;
00206 }
00207 return (s >> n + 1) + 1;
00208 }
00209
00210
00211
00212
00213 big_int e_u (std::size_t kbits )
00214 {
00215 return e ( kbits ) - 1;
00216 }
00217
00218 big_int e_o (std::size_t kbits )
00219 {
00220 return e ( kbits ) + 1;
00221 }
00222
00223
00224 big_int e ( std::size_t kbits )
00225 {
00226 std::size_t n = int ( kbits - 2 ) / 3 + 1;
00227 if ( n <= 19 ) n = 20;
00228
00229 std::size_t pos = log ( (long double)n ) / log ( 2.0l ) + 2;
00230 std::size_t counter = 1;
00231 big_int s;
00232
00233 kbits++;
00234 big_int a = pow2<big_int> ( kbits + pos );
00235
00236 s = s + a;
00237 while ( counter < n && a != 0 )
00238 {
00239 a = ( a / counter);
00240 s = s + a;
00241 counter++;
00242 }
00243 return ( s >> pos ) + 1;
00244 }
00245
00246
00247 }