1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
#include<vector>
#include<cstring>
#include<string>
#include<cmath>
#include"eku\bytes.h"
#include"eku\hexconv.h"
/*
Luint - Large Unsigned int
This data type uses a std::vector to store ints which
concatenate bitwise to make a large unsigned int.
The smallest bits are stored in a[0], larger bits in a[1]
and so on. The size of the luint is extensible.
*/
namespace eku
{
typedef unsigned __int32 styp;
typedef unsigned __int64 btyp;
const static unsigned ssize=sizeof(styp);
const static unsigned bsize=sizeof(btyp);
const static unsigned sbits=ssize*CHAR_BIT;
const static unsigned bbits=ssize*CHAR_BIT;
class luint
{public:
//data-members--------------------------------------------------------------------
std::vector<styp> a;
bool sign; //+ve sign is true and -ve sign is false.
//As luint is unsigned, -ve sign means error
//-ve sign can be encountered while using operator- or operator--
//Conversion-to-double------------------------------------------------------------
unsigned exponent()const;
//gets integral part of logarithm of *this to the base 2
template<class dtyp>
//dtyp can be double, float, long double, etc.
dtyp signif(int prec=4)const;
template<class dtyp>
//dtyp can be double, float, long double, etc.
dtyp as_double(int prec=4)const
{return ldexp(signif<dtyp>(prec),exponent());}
};
template<class dtyp>
//dtyp can be double, float, long double, etc.
dtyp luint::signif(int prec/*=4*/)const
{
int i,j;dtyp d=1;
if(a.size()==0)return 0;
for(i=int(a.size())-1,j=0;i>=0 && j<prec;--i,++j)
{d*=dtyp(a[i])*ldexp(double(1),(-j)*sbits);}
return frexp(d,&i);
}
unsigned luint::exponent()const
//gets integral part of logarithm of *this to the base 2
{
if(a.size()==0)return 0;
styp v=a.back();
unsigned exp=0;
while(v){exp++;v>>=1;}
return exp+(a.size()-1)*sbits;
}
}
|