finishing bitvector
This commit is contained in:
parent
e42987061f
commit
50b2447535
41
bitvector.h
41
bitvector.h
@ -21,8 +21,12 @@
|
|||||||
|
|
||||||
#include "vec.h"
|
#include "vec.h"
|
||||||
#include "numbers.h"
|
#include "numbers.h"
|
||||||
|
#include "laerror.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
//TODO: if efficiency is requires, make also a monic_bitvector, which will not store the leading 1 explicitly
|
||||||
|
//and then the field operations will be done without any resize
|
||||||
|
//To avoid confusion this class must NOT be derived from bitvector and have only explicit constructor conversion
|
||||||
|
|
||||||
namespace LA {
|
namespace LA {
|
||||||
//compressed storage of large bit vectors
|
//compressed storage of large bit vectors
|
||||||
@ -46,6 +50,19 @@ public:
|
|||||||
explicit bitvector (const unsigned int n):NRVec<bitvector_block>((n+blockbits-1)/blockbits) {modulo=n%blockbits; memset(v,0,nn*sizeof(bitvector_block));};
|
explicit bitvector (const unsigned int n):NRVec<bitvector_block>((n+blockbits-1)/blockbits) {modulo=n%blockbits; memset(v,0,nn*sizeof(bitvector_block));};
|
||||||
bitvector (const bitvector_block a, const unsigned int n):NRVec<bitvector_block>(a,(n+blockbits-1)/blockbits) {modulo=n%blockbits;};
|
bitvector (const bitvector_block a, const unsigned int n):NRVec<bitvector_block>(a,(n+blockbits-1)/blockbits) {modulo=n%blockbits;};
|
||||||
bitvector(const bitvector &rhs) : NRVec<bitvector_block>(rhs) {modulo=rhs.modulo;};
|
bitvector(const bitvector &rhs) : NRVec<bitvector_block>(rhs) {modulo=rhs.modulo;};
|
||||||
|
explicit bitvector(const uint8_t *data, const unsigned int n): NRVec<bitvector_block>((n+blockbits-1)/blockbits)
|
||||||
|
{
|
||||||
|
modulo=n%blockbits;
|
||||||
|
if(endianity()) laerror("not portable to big endian");
|
||||||
|
else memcpy(&v[0],data,(n+7)/8);
|
||||||
|
zero_padding();
|
||||||
|
};
|
||||||
|
void getdata(uint8_t *data)
|
||||||
|
{
|
||||||
|
if(endianity()) laerror("not portable to big endian");
|
||||||
|
else memcpy(data,&v[0],(size()+7)/8);
|
||||||
|
}
|
||||||
|
|
||||||
//operator= seems to be correctly synthetized by the compiler
|
//operator= seems to be correctly synthetized by the compiler
|
||||||
//override dereferencing to address single bits, is however possible
|
//override dereferencing to address single bits, is however possible
|
||||||
//only in the const context (otherwise we would have to define a type which, when assigned to, changes a single bit - possible but probably inefficient)
|
//only in the const context (otherwise we would have to define a type which, when assigned to, changes a single bit - possible but probably inefficient)
|
||||||
@ -57,9 +74,27 @@ public:
|
|||||||
bitvector_block getblock(const unsigned int i) const {return v[i];}; //integer interpretation
|
bitvector_block getblock(const unsigned int i) const {return v[i];}; //integer interpretation
|
||||||
void setblock(const unsigned int i, const bitvector_block b) {v[i]=b;};
|
void setblock(const unsigned int i, const bitvector_block b) {v[i]=b;};
|
||||||
int getblocksize() const {return 8*sizeof(bitvector_block);};
|
int getblocksize() const {return 8*sizeof(bitvector_block);};
|
||||||
void set(const unsigned int i) {v[i/blockbits] |= (1UL<<(i%blockbits));};
|
void set(const unsigned int i)
|
||||||
void reset(const unsigned int i) {v[i/blockbits] &= ~(1UL<<(i%blockbits));};
|
{
|
||||||
void flip(const unsigned int i) {v[i/blockbits] ^= (1UL<<(i%blockbits));};
|
#ifdef DEBUG
|
||||||
|
if(i>=size()) laerror("bitvector index out of range in");
|
||||||
|
#endif
|
||||||
|
v[i/blockbits] |= (1UL<<(i%blockbits));
|
||||||
|
};
|
||||||
|
void reset(const unsigned int i)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
if(i>=size()) laerror("bitvector index out of range in");
|
||||||
|
#endif
|
||||||
|
v[i/blockbits] &= ~(1UL<<(i%blockbits));
|
||||||
|
};
|
||||||
|
void flip(const unsigned int i)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
if(i>=size()) laerror("bitvector index out of range in");
|
||||||
|
#endif
|
||||||
|
v[i/blockbits] ^= (1UL<<(i%blockbits));
|
||||||
|
};
|
||||||
const bool assign(const unsigned int i, const bool r) {if(r) set(i); else reset(i); return r;};
|
const bool assign(const unsigned int i, const bool r) {if(r) set(i); else reset(i); return r;};
|
||||||
void clear() {copyonwrite(true); memset(v,0,nn*sizeof(bitvector_block));};
|
void clear() {copyonwrite(true); memset(v,0,nn*sizeof(bitvector_block));};
|
||||||
void fill() {memset(v,0xff,nn*sizeof(bitvector_block));};
|
void fill() {memset(v,0xff,nn*sizeof(bitvector_block));};
|
||||||
|
24
numbers.cc
24
numbers.cc
@ -117,6 +117,23 @@ return y;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//avoiding overflow which would occur very soon in (x*y)%m
|
||||||
|
template <typename N>
|
||||||
|
N multmod(N x, N y, const N &m)
|
||||||
|
{
|
||||||
|
N sum=0;
|
||||||
|
if(y==0) return 0;
|
||||||
|
while(x)
|
||||||
|
{
|
||||||
|
if(x&1) sum= (sum+y)%m;
|
||||||
|
x>>=1;
|
||||||
|
y = (y<<1)%m; //still can overflow here but for much larger numbers
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename N>
|
template <typename N>
|
||||||
N powmod(const N &x, N i, const N &m)
|
N powmod(const N &x, N i, const N &m)
|
||||||
{
|
{
|
||||||
@ -126,14 +143,14 @@ N y,z;
|
|||||||
z=x%m;
|
z=x%m;
|
||||||
while(!(i&1))
|
while(!(i&1))
|
||||||
{
|
{
|
||||||
z = (z*z)%m;
|
z = multmod(z,z,m);
|
||||||
i >>= 1;
|
i >>= 1;
|
||||||
}
|
}
|
||||||
y=z;
|
y=z;
|
||||||
while((i >>= 1)/*!=0*/)
|
while((i >>= 1)/*!=0*/)
|
||||||
{
|
{
|
||||||
z = (z*z)%m;
|
z = multmod(z,z,m);
|
||||||
if(i&1) y = (y*z)%m;
|
if(i&1) y = multmod(y,z,m);
|
||||||
}
|
}
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
@ -151,6 +168,7 @@ template N nextprime(N x); \
|
|||||||
template std::ostream & operator<<(std::ostream &s, const FACTORIZATION<N> &x); \
|
template std::ostream & operator<<(std::ostream &s, const FACTORIZATION<N> &x); \
|
||||||
template N pow(const N &x, N i); \
|
template N pow(const N &x, N i); \
|
||||||
template N powmod(const N &x, N i, const N &m); \
|
template N powmod(const N &x, N i, const N &m); \
|
||||||
|
template N multmod(N x, N i, const N &m); \
|
||||||
template N eulerphi(const FACTORIZATION<N> &f); \
|
template N eulerphi(const FACTORIZATION<N> &f); \
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,6 +65,10 @@ N pow(const N &x, N i);
|
|||||||
template <typename N>
|
template <typename N>
|
||||||
N powmod(const N &x, N i, const N &m);
|
N powmod(const N &x, N i, const N &m);
|
||||||
|
|
||||||
|
template <typename N>
|
||||||
|
N multmod(N x, N y, const N &m);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}//namespace
|
}//namespace
|
||||||
#endif
|
#endif
|
||||||
|
6
t.cc
6
t.cc
@ -2944,6 +2944,12 @@ if(0)
|
|||||||
uint64_t n;
|
uint64_t n;
|
||||||
cin >>n;
|
cin >>n;
|
||||||
cout <<factorization(n)<<" phi = "<<eulerphi(n)<<endl;
|
cout <<factorization(n)<<" phi = "<<eulerphi(n)<<endl;
|
||||||
|
uint64_t a;
|
||||||
|
do {
|
||||||
|
a=RANDINT64()%n;
|
||||||
|
|
||||||
|
}while(gcd(a,n)!=1);
|
||||||
|
cout <<"E-F test "<<powmod(a,eulerphi(n),n)<<endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(0)
|
if(0)
|
||||||
|
Loading…
Reference in New Issue
Block a user