mawinkle 6 år sedan
förälder
incheckning
45f77d60a5
2 ändrade filer med 129 tillägg och 16 borttagningar
  1. 117 10
      BigInt64.hpp
  2. 12 6
      test.cpp

+ 117 - 10
BigInt64.hpp

@@ -50,6 +50,8 @@ struct BigInt{
 	inline BigInt(std::initializer_list<uint64_t>&& l) : data(std::move(l)), signum(1){}
 	template<typename InputIterator>
 	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();}
@@ -77,14 +79,18 @@ struct BigInt{
 		if(size() > o.size()){
 			it1 += size() - o.size();
 			auto _t = begin();
-			while(_t != it1)
+			while(_t != it1){
 				if(*_t)return false;
+				++_t;
+			}
 		}
 		else if(size() < o.size()){
 			it2 += o.size() - size();
 			auto _t = o.begin();
-			while(_t != it2)
+			while(_t != it2){
 				if(*_t)return true;
+				++_t;
+			}
 		}
 		while(it1 != end() && it2 != o.end()){
 			if(*(it1) < *(it2))return true;
@@ -105,14 +111,18 @@ struct BigInt{
 		if(size() > o.size()){
 			it1 += size() - o.size();
 			auto _t = begin();
-			while(_t != it1)
+			while(_t != it1){
 				if(*_t)return true;
+				++_t;
+			}
 		}
 		else if(size() < o.size()){
 			it2 += o.size() - size();
 			auto _t = o.begin();
-			while(_t != it2)
+			while(_t != it2){
 				if(*_t)return false;
+				++_t;
+			}
 		}
 		while(it1 != end() && it2 != o.end()){
 			if(*(it1) > *(it2))return true;
@@ -133,14 +143,18 @@ struct BigInt{
 		if(size() > o.size()){
 			it1 += size() - o.size();
 			auto _t = begin();
-			while(_t != it1)
+			while(_t != it1){
 				if(*_t)return true;
+				++_t;
+			}
 		}
 		else if(size() < o.size()){
 			it2 += o.size() - size();
 			auto _t = o.begin();
-			while(_t != it2)
+			while(_t != it2){
 				if(*_t)return false;
+				++_t;
+			}
 		}
 		while(it1 != end() && it2 != o.end()){
 			if(*(it1) < *(it2))return true;
@@ -161,14 +175,18 @@ struct BigInt{
 		if(size() > o.size()){
 			it1 += size() - o.size();
 			auto _t = begin();
-			while(_t != it1)
+			while(_t != it1){
 				if(*_t)return true;
+				++_t;
+			}
 		}
 		else if(size() < o.size()){
 			it2 += o.size() - size();
 			auto _t = o.begin();
-			while(_t != it2)
+			while(_t != it2){
 				if(*_t)return false;
+				++_t;
+			}
 		}
 		while(it1 != end() && it2 != o.end()){
 			if(*(it1) > *(it2))return true;
@@ -189,14 +207,18 @@ struct BigInt{
 		if(size() > o.size()){
 			it1 += size() - o.size();
 			auto _t = begin();
-			while(_t != it1)
+			while(_t != it1){
 				if(*_t)return false;
+				++_t;
+			}
 		}
 		else if(size() < o.size()){
 			it2 += o.size() - size();
 			auto _t = o.begin();
-			while(_t != it2)
+			while(_t != it2){
 				if(*_t)return false;
+				++_t;
+			}
 		}
 		while(it1 != end() && it2 != o.end()){
 			if(*(it1) != *(it2))return false;
@@ -213,11 +235,13 @@ struct BigInt{
 	inline void setZero(){
 		for(auto it = begin();it != end();it++)*it = 0;
 	}
+	
 	inline void trim(){
 		while(data[0] == 0 && data.size() != 0){
 			data.pop_front();
 		}
 	}
+	
 	inline BigInt div(uint64_t d)const{
 		BigInt ret = *this;
 		lui carry = 0;
@@ -249,6 +273,51 @@ struct BigInt{
 		}
 		return carry;
 	}
+	
+	inline BigInt& bitshiftLeft(int c){
+		if(c < 0)return bitshiftRight(-c);
+		if((unsigned int)c >= size() * sizeof(uint64_t)){std::fill(begin(),end(),0);return *this;}
+		unsigned int sh = c % 64;
+		unsigned int jmp = c / 64;
+		auto it1 = begin(); 
+		auto it2 = it1 + jmp;
+		auto beforeEnd = end() - 1;
+		while(it2 != beforeEnd){
+			*it1 = (*it2 << sh);
+			*it1 |= (*(it2 + 1) >> (64 - sh));
+			++it1;++it2;
+		}
+		++it1;++it2;
+		*it1 = (*it2 << sh);
+		while(it1 != end()){
+			*it1 = 0;
+			++it1;
+		}
+		return *this;
+	}
+	
+	inline BigInt& bitshiftRight(int c){
+		if(c < 0)return bitshiftLeft(-c);
+		if((unsigned int)c >= size() * sizeof(uint64_t)){std::fill(begin(),end(),0);return *this;}
+		unsigned int sh = c % 64;
+		unsigned int jmp = c / 64;
+		auto it1 = rbegin(); 
+		auto it2 = it1 + jmp;
+		auto beforeRend = rend() - 1;
+		while(it2 != beforeRend){
+			*it1 = (*it2 >> sh);
+			*it1 |= (*(it2 + 1) << (64 - sh));
+			++it1;++it2;
+		}
+		++it1;++it2;
+		*it1 = (*it2 << sh);
+		while(it1 != rend()){
+			*it1 = 0;
+			++it1;
+		}
+		return *this;
+	}
+	
 	inline BigInt& chunkshiftLeft(int c){
 		if(c < 0)return chunkshiftRight(-c);
 		if((unsigned int)c >= size()){std::fill(begin(),end(),0);return *this;}
@@ -258,6 +327,7 @@ struct BigInt{
 		while(it1 != data.end())*(it1++) = 0;
 		return *this;
 	}
+	
 	inline BigInt& chunkshiftRight(int c){
 		if(c < 0)return chunkshiftLeft(-c);
 		if((unsigned int)c >= size()){std::fill(begin(),end(),0);return *this;}
@@ -267,11 +337,36 @@ struct BigInt{
 		while(it1 != data.rend())*(it1++) = 0;
 		return *this;
 	}
+	inline BigInt bitshiftLeft(int c)const{
+		if(c < 0)return bitshiftRight(-c);
+		BigInt _this = *this;
+		_this.bitshiftLeft(c);
+		return _this;
+	}
+	inline BigInt bitshiftRight(int c)const{
+		if(c < 0)return bitshiftLeft(-c);
+		BigInt _this = *this;
+		_this.bitshiftRight(c);
+		return _this;
+	}
+	inline BigInt chunkshiftLeft(int c)const{
+		if(c < 0)return chunkshiftRight(-c);
+		BigInt _this = *this;
+		_this.chunkshiftLeft(c);
+		return _this;
+	}
+	inline BigInt chunkshiftRight(int c)const{
+		if(c < 0)return chunkshiftLeft(-c);
+		BigInt _this = *this;
+		_this.chunkshiftRight(c);
+		return _this;
+	}
 	inline BigInt add(const BigInt& o){
 		BigInt ret = *this;
 		ret.adda(o);
 		return ret;
 	}
+	
 	inline BigInt& adda(const BigInt& o){
 		while(size() < o.size())data.push_front(0);
 		bool carry = 0;
@@ -285,6 +380,7 @@ struct BigInt{
 		}
 		while(it1 != rend() && carry){
 			carry = __builtin_uaddll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
+			++it1;
 		}
 		if(carry)data.push_front(1);
 		return *this;
@@ -302,6 +398,7 @@ struct BigInt{
 		}
 		while(it1 != rend() && carry){
 			carry = __builtin_usubll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
+			++it1;
 		}
 		return *this;
 	}
@@ -373,4 +470,14 @@ struct BigInt{
 		return std::string(c_str.rbegin(), c_str.rend());
 	}
 };
+namespace std{
+	template<>
+	struct hash<BigInt>{
+		size_t operator()(const BigInt& o){
+			size_t ret = 0;
+			std::for_each(o.begin(), o.end(), [&ret](const uint64_t& ui){ret ^= ui;});
+			return ret;
+		}
+	};
+}
 #endif //BIGINT64_HPP

+ 12 - 6
test.cpp

@@ -1,6 +1,6 @@
 #include "socketio.hpp"
 #include "BigInt64.hpp"
-
+#include <xoshiro.hpp>
 #include <iostream>
 #include <chrono>
 unsigned long long nanoTime(){
@@ -27,13 +27,19 @@ std::ostream& operator<< <char>(std::ostream& out, std::vector<char> o){
 	return out;
 }
 int main(){
-	BigInt a = {20,20};
-	BigInt b = {1};
-	for(int i = 0;i < 30;i++){
+	xoshiro_256 gen(42);
+	BigInt a(gen, 2);
+	a[0] >>= 30;
+	std::cout << a.toString() << std::endl;
+	a.bitshiftLeft(1);
+	std::cout << a.toString() << std::endl;
+	for(unsigned int i = 2;true;i *= 2){
+		BigInt a(gen, i);
+		BigInt b(gen, i);
 		auto t1 = nanoTime();
-		a.suba(b);
+		a = a.mult(b);
 		auto t2 = nanoTime();
-		std::cout << a.rawString() << std::endl;
+		std::cout << i << ", " << ((double)((t2 - t1) / 1000) / 1000.0d) << " ms \t\t" << (std::hash<BigInt>()(a) % 10) << std::endl;
 	}
 }
 int mian(){