big_const.cpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     big_const.cpp -- functions that calculates several constants.
00004         See big_const.hpp file.
00005 
00006     This file is a part of the Arageli library.
00007 
00008     Copyright (C) Alexander Pshenichnikov, 2005--2006
00009     Copyright (C) Nikolay Santalov, 2005--2006
00010     
00011     University of Nizhni Novgorod, Russia
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                                 // possible loss of data
00025 
00026 namespace Arageli
00027 {
00028 
00029 /***************************** ln(1.25)****************************************/
00030 big_int ln1_25 ( std::size_t kbits ) //calculate ln(1.25)
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;//log2( 2n ) + 2
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) //Taylor series
00043   {
00044         a = pow2<big_int>(kbits + pos - (counter<<1))/counter;//(1/4^n)*(1/n)
00045         counter++;
00046         s = s + a;
00047         a = pow2<big_int>(kbits + pos - (counter<<1))/counter;//(1/4^n)*(1/n)
00048         counter++;
00049         s = s - a - 1;
00050   }
00051   return (s >> pos ) + 1;//delete excess bits 
00052 }
00053 
00054 big_int ln1_25_o(std::size_t kbits)//calculate ln(1.25) with overflow
00055 {
00056     return ln1_25 ( kbits ) + 1;
00057 }
00058 
00059 big_int ln1_25_u ( std::size_t kbits )//calculate ln(1.25) with underflow
00060 {
00061   return ln1_25 ( kbits ) - 1;
00062 }
00063 
00064 /***********************************ln2*****************************************/
00065 big_int ln2 ( std::size_t kbits )//calculate ln(2)
00066 {
00067   std::size_t n = ( kbits - 1 )/ 3 + 1;
00068   std::size_t pos = log ( (long double)n ) / log ( 2.0l ) + 2;//log2( n ) + 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 ) //Taylor series
00077   {
00078     //b = pow2<big_int>(kbits + n) / 81; it is good to verify that always a/(b*c)==(a/b)/c 
00079     a = (a * ((counter << 1) - 1))/(((counter << 1) + 1) * 9);
00080     s = s + a;
00081     counter++;
00082   }
00083   
00084   return (s >> pos - 1) + 1 ;//don't forget to multiply by two 
00085 }
00086 
00087 big_int ln2_u ( std::size_t kbits )//calculate ln(2) with underflow
00088 {
00089     return ln2 ( kbits ) - 1;
00090 }
00091 
00092 big_int ln2_o(std::size_t kbits)//calculate ln(1.25) with overflow
00093 {
00094     return ln2 ( kbits ) + 1;
00095 }
00096 
00097 
00098 /******************************log2(10)*****************************************/
00099 big_int log2_10 ( std::size_t nbits ) //calculate log2_10 with nbits significant bits  
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 ) //calculate log2_10 with nbits significant bits with overflow  
00106 { 
00107     return log2_10 ( nbits ) + 1; 
00108 }
00109 
00110 big_int log2_10_u ( std::size_t nbits ) //calculate log2_10 with nbits significant bits with underflow  
00111 {
00112     return log2_10 ( nbits ) + 1;
00113 }
00114 
00115 /******************************lg(2)*****************************************/
00116 
00117 big_int lg_2_o ( std::size_t nbits ) //calculate lg2 with nbits significant bits with overflow  
00118 { 
00119     return lg_2 ( nbits ) + 1;
00120 }
00121 
00122 big_int lg_2_u ( std::size_t nbits ) //calculate lg2 with nbits significant bits with underflow  
00123 {
00124     return lg_2 ( nbits ) - 1;
00125 }
00126 
00127 big_int lg_2 ( std::size_t nbits ) //calculate lg2 with nbits significant bits  
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 /*********************************e^x*********************************************/
00136 
00137 // calculate exp ( x ) with kbits significant bits with underflow
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 // calculate exp ( x ) with k_bits significant bits with overflow
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 // calculate exp ( x ) with k_bits significant bits with overflow
00152 big_int exp (big_int arg, std::size_t kbits, int factor)
00153 {
00154     // there 0 < x < 1 x =  arg/2^(arg.length() + factor ) 
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;//log2( n ) + 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 ;//Teylor series  
00170         s = s + a;
00171         counter++;
00172     }
00173     return ( s >> pos ) + 1  ; 
00174 }
00175 
00176 
00177 /*****************************2^x***********************************************/ 
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 ;//Teylor series  
00204         s = s + a;
00205         counter++;
00206     }
00207     return (s >> n + 1)  +  1;  
00208 }
00209 
00210 
00211 /***************************e ****************************************************/
00212 
00213 big_int e_u (std::size_t kbits  )//e number with underflow  
00214 {
00215     return e ( kbits ) - 1;
00216 }
00217 
00218 big_int e_o (std::size_t kbits  )//e number with overflow  
00219 {
00220     return e ( kbits ) + 1;
00221 }
00222 
00223 
00224 big_int e ( std::size_t kbits )//e number with overflow  
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;//log2( n ) + 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);//Teylor series  
00240         s = s + a;
00241         counter++;
00242     }
00243     return ( s >> pos ) + 1;    
00244 }
00245 /**********************************************************************************/
00246 
00247 }

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