mawinkle 6 rokov pred
rodič
commit
bb42509915
2 zmenil súbory, kde vykonal 138 pridanie a 51 odobranie
  1. 130 47
      BigInt64.hpp
  2. 8 4
      test.cpp

+ 130 - 47
BigInt64.hpp

@@ -55,31 +55,44 @@ struct BigInt{
 	inline BigInt(InputIterator begin, InputIterator end) : data(begin, end), signum(1){}
 	template<typename RNG>
 	inline BigInt(RNG& rng, size_t length) : data(length, 0), signum(1){std::generate(data.begin(),data.end(), [&rng](){return rng();});}
-	std::deque<uint64_t>::iterator begin(){return data.begin();}
-	std::deque<uint64_t>::iterator end(){return data.end();}
-	std::deque<uint64_t>::reverse_iterator rbegin(){return data.rbegin();}
-	std::deque<uint64_t>::reverse_iterator rend(){return data.rend();}
-	std::deque<uint64_t>::const_iterator begin()const{return data.begin();}
-	std::deque<uint64_t>::const_iterator end()const{return data.end();}
-	std::deque<uint64_t>::const_reverse_iterator rbegin()const{return data.rbegin();}
-	std::deque<uint64_t>::const_reverse_iterator rend()const{return data.rend();}
-	BigInt& operator=(const BigInt& o){
-		data = o.data;
-		signum = o.signum;
-		return *this;
+	inline std::deque<uint64_t>::iterator begin(){return data.begin();}
+	inline std::deque<uint64_t>::iterator end(){return data.end();}
+	inline std::deque<uint64_t>::reverse_iterator rbegin(){return data.rbegin();}
+	inline std::deque<uint64_t>::reverse_iterator rend(){return data.rend();}
+	inline std::deque<uint64_t>::const_iterator begin()const{return data.begin();}
+	inline std::deque<uint64_t>::const_iterator end()const{return data.end();}
+	inline std::deque<uint64_t>::const_reverse_iterator rbegin()const{return data.rbegin();}
+	inline std::deque<uint64_t>::const_reverse_iterator rend()const{return data.rend();}
+	inline uint64_t& operator[](size_t i){return data[i];}
+	inline const uint64_t& operator[](size_t i)const{return data[i];}
+	inline size_t size()const{return data.size();}
+	inline auto cbegin()const{return data.cbegin();}
+	inline auto cend()const{return data.cend();}
+	inline auto crbegin()const{return data.crbegin();}
+	inline auto crend()const{return data.crend();}
+	inline BigInt& operator=(const BigInt& o){signum = o.signum;std::fill(std::copy(o.rbegin(),o.rend(),rbegin()),rend(),0);return *this;}
+	inline BigInt& operator=(BigInt&& o){data = std::move(o.data);signum = o.signum;return *this;}
+	inline size_t bitscanForward()const{
+		auto it = begin();
+		size_t s = 0;
+		while(*it == 0 && it != end()){
+			++it;
+			s += 64;
+		}
+		if(it == end())return s + 64;
+		return s + __builtin_clzll(*it);
 	}
-	BigInt& operator=(BigInt&& o){
-		data = std::move(o.data);
-		signum = o.signum;
-		return *this;
+	inline size_t bitscanReverse()const{
+		auto it = rbegin();
+		size_t s = 0;
+		while(*it == 0 && it != rend()){
+			++it;
+			s += 64;
+		}
+		if(it == rend())return s + 64;
+		return s + __builtin_ctzll(*it);
 	}
-	uint64_t& operator[](size_t i){return data[i];}
-	const uint64_t& operator[](size_t i)const{return data[i];}
-	size_t size()const{return data.size();}
-	auto cbegin()const{return data.cbegin();}
-	auto cend()const{return data.cend();}
-	auto crbegin()const{return data.crbegin();}
-	auto crend()const{return data.crend();}
+	
 	inline bool operator<(const BigInt& o)const{
 		if(signum > o.signum){
 			return false;
@@ -239,6 +252,9 @@ struct BigInt{
 		}
 		return true;
 	}
+	inline bool operator==(uint64_t o){
+		return size() == 1 && *rbegin() == o;
+	}
 	inline bool isZero()const{
 		for(auto it = data.begin();it != data.end();it++){
 			if(*it)return false;
@@ -311,6 +327,31 @@ struct BigInt{
 		return *this;
 	}
 	
+	inline BigInt& bitshiftLeft_expand(int c){
+		if(c < 0)return bitshiftRight(-c);
+		unsigned int sh = c % 64;
+		unsigned int jmp = c / 64;
+		int insert_count = std::max((size_t)0, jmp - bitscanForward() / 64 + 1);
+		while(insert_count --> 0)
+			data.push_front(0);
+		auto it1 = begin(); 
+		auto it2 = it1 + jmp;
+		auto beforeEnd = end() - 1;
+		while(it2 != beforeEnd){
+			*it1 = (*it2 << sh);
+			if(sh)
+			*it1 |= (*(it2 + 1) >> (64 - sh));
+			++it1;++it2;
+		}
+		*it1 = (*it2 << sh);
+		++it1;++it2;
+		while(it1 != end()){
+			*it1 = 0;
+			++it1;
+		}
+		return *this;
+	}
+	
 	inline BigInt& bitshiftRight(int c){
 		if(c < 0)return bitshiftLeft(-c);
 		unsigned int sh = c % 64;
@@ -333,63 +374,63 @@ struct BigInt{
 		}
 		return *this;
 	}
-	BigInt operator<<(int c)const{
+	inline BigInt operator<<(int c)const{
 		BigInt ret = *this;
 		ret.bitshiftLeft(c);
 		return ret;
 	}
 	
-	BigInt operator>>(int c)const{
+	inline BigInt operator>>(int c)const{
 		BigInt ret = *this;
 		ret.bitshiftRight(c);
 		return ret;
 	}
 	
-	BigInt& operator<<=(int c){
+	inline BigInt& operator<<=(int c){
 		return bitshiftLeft(c);
 	}
 	
-	BigInt& operator>>=(int c){
+	inline BigInt& operator>>=(int c){
 		return bitshiftRight(c);
 	}
 	
-	BigInt& operator&=(const BigInt& o){
+	inline BigInt& operator&=(const BigInt& o){
 		auto it1 = rbegin();
 		auto it2 = o.rbegin();
 		while(it1 != rend() && it2 != o.rend())
 			*(it1++) &= *(it2++);
 		return *this;
 	}
-	BigInt& operator|=(const BigInt& o){
+	inline BigInt& operator|=(const BigInt& o){
 		auto it1 = rbegin();
 		auto it2 = o.rbegin();
 		while(it1 != rend() && it2 != o.rend())
 			*(it1++) |= *(it2++);
 		return *this;
 	}
-	BigInt& operator^=(const BigInt& o){
+	inline BigInt& operator^=(const BigInt& o){
 		auto it1 = rbegin();
 		auto it2 = o.rbegin();
 		while(it1 != rend() && it2 != o.rend())
 			*(it1++) ^= *(it2++);
 		return *this;
 	}
-	BigInt operator&(const BigInt& o)const{
+	inline BigInt operator&(const BigInt& o)const{
 		BigInt ret(*this);
 		ret &= o;
 		return ret;
 	}
-	BigInt operator|(const BigInt& o)const{
+	inline BigInt operator|(const BigInt& o)const{
 		BigInt ret(*this);
 		ret |= o;
 		return ret;
 	}
-	BigInt operator^(const BigInt& o)const{
+	inline BigInt operator^(const BigInt& o)const{
 		BigInt ret(*this);
 		ret ^= o;
 		return ret;
 	}
-	int bitDifference(const BigInt& o){
+	inline int bitDifference(const BigInt& o){
 		int pos1(0),pos2(0);
 		auto it1 = begin();
 		auto it2 = o.begin();
@@ -504,17 +545,51 @@ struct BigInt{
 		return *this;
 	}
 	inline BigInt& moda(const BigInt& o){
+		assert(!o.isZero());
 		if(o > *this)return *this;
+		BigInt mo = o;
+		mo = o;
+		int bd = bitDifference(o);
+		mo.bitshiftLeft_expand(bd);
+		if(mo > *this)mo.bitshiftRight(1);
+		this->suba(mo);
+		if(*this < o)return *this;
 		while(true){
-			BigInt mo = o;
-			int bd = bitDifference(o);
-			mo.bitshiftLeft(bd);
-			if(mo > *this)mo.bitshiftRight(1);
+			bd = mo.bitDifference(*this);
+			mo >>= bd;
+			mo.trim();
+			if(mo > *this)mo >>= 1;
 			this->suba(mo);
-			if(*this < o)break;
+			if(*this < o)return *this;
 		}
 		return *this;
 	}
+	inline bool even(){
+		return !(*rbegin() & 1);
+	}
+	inline BigInt modPow(BigInt o, const BigInt& mod)const{
+		BigInt t = *this;
+		BigInt odd(1);
+		while(true){
+			if(o.even()){
+				t = t.mult(t);
+				t.trim();
+				t.moda(mod);
+				o.div(2);
+			}
+			else{
+				odd = odd.mult(t);
+				odd.moda(mod);
+				odd.trim();
+				t.trim();
+				t.moda(mod);
+				o.suba(BigInt(1));
+			}
+			std::cout << "Reduced" << std::endl;
+			o.trim();
+			if(o == 1){t = t.mult(odd);t.moda(mod);return t;}
+		}
+	}
 	inline BigInt mult(const BigInt& o)const{
 		BigInt result(size() + o.size() + 1,0);
 		BigInt temp(size() + o.size() + 1,0);
@@ -534,10 +609,16 @@ struct BigInt{
 			temp.setZero();
 		}
 		result.trim();
+		BigInt krep = result;
+		krep.moda(*this);
+		assert(krep.isZero());
+		krep = result;
+		krep.moda(o);
+		assert(krep.isZero());
 		return result;
 	}
 	
-	inline std::string rawString(){
+	inline std::string rawString()const{
 		std::string s = "";
 		bool flag;
 		for(unsigned int i = 0;i < size();i++){
@@ -548,10 +629,10 @@ struct BigInt{
 		}
 		return s;
 	}
-	inline std::string bitString(){
+	inline std::string bitString()const{
 		auto it = begin();
 		std::string ret = "";
-		std::cout << size() << "; " << std::flush;
+		//std::cout << size() << "; " << std::flush;
 		while(it != end()){
 			std::bitset<64> bits(*it);
 			for(unsigned int i = 0;i < 64;i++){
@@ -561,10 +642,10 @@ struct BigInt{
 		}
 		return ret;
 	}
-	inline std::string toString(){
+	inline std::string toString()const{
+		if(isZero())return std::to_string(0);
 		std::deque<char> c_str;
 		const uint64_t q = 1000000000000000000ULL;
-		//c_str.reserve(size() * 19);
 		BigInt diver = *this;
 		while(!diver.isZero()){
 			std::string frac = std::to_string(diver.mod(q));
@@ -584,8 +665,10 @@ struct BigInt{
 		return std::string(it, c_str.end());
 	}
 	
-	inline std::string toString(unsigned int base){
-		if(isZero())return std::string("0");
+	inline std::string toString(unsigned int base)const{
+		if(isZero())return std::to_string(0);
+		if(base == 2)return bitString();
+		if(base == 10)return toString();
 		std::vector<char> c_str;
 		c_str.reserve(size() * (unsigned int)(64.0 * std::log(2) / std::log((double)base)));
 		BigInt diver = *this;
@@ -599,7 +682,7 @@ struct BigInt{
 namespace std{
 	template<>
 	struct hash<BigInt>{
-		size_t operator()(const BigInt& o){
+		inline size_t operator()(const BigInt& o)const{
 			size_t ret = 0;
 			std::for_each(o.begin(), o.end(), [&ret](const uint64_t& ui){ret ^= ui;});
 			return ret;

+ 8 - 4
test.cpp

@@ -28,10 +28,14 @@ std::ostream& operator<< <char>(std::ostream& out, std::vector<char> o){
 }
 int main(){
 	xoshiro_256 gen(1);
-	BigInt a(256);
-	BigInt b(8);
-	a.moda(b);
-	std::cout << a.toString() << "\n";
+	BigInt a(gen,10);
+	BigInt b(gen,8);
+	BigInt mod(gen, 10);
+	std::cout << "a: " << a.toString() << "\n";
+	a = a.modPow(b,mod);
+	std::cout << "b: " << b.toString() << "\n";
+	std::cout << "mod: " << mod.toString() << "\n";
+	std::cout << "Result: " << a.toString() << "\n";
 }
 /*int mian(){
 	cppsocket sock("192.168.178.79", 80);