mawinkle 6 лет назад
Родитель
Сommit
02dfb06532
2 измененных файлов с 39 добавлено и 11 удалено
  1. 30 9
      BigInt64.hpp
  2. 9 2
      test.cpp

+ 30 - 9
BigInt64.hpp

@@ -48,10 +48,12 @@ struct BigInt{
 	inline BigInt(long long a) : data(1, std::abs(a)),signum(::signum(a)){}
 	inline BigInt(const std::initializer_list<uint64_t>& l) : data(l), signum(1){}
 	inline BigInt(std::initializer_list<uint64_t>&& l) : data(std::move(l)), signum(1){}
+	inline BigInt(const BigInt& o) : data(o.data), signum(o.signum){}
+	inline BigInt(BigInt&& o) : data(std::move(o.data)), signum(o.signum){}
 	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();});}
+	inline BigInt(RNG& rng, size_t length) : data(length, 0), signum(1){auto it = data.begin();while(it != data.end())*(it++) = 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();}
@@ -60,6 +62,14 @@ struct BigInt{
 	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;
+	}
+	BigInt& operator=(BigInt&& o){
+		data = std::move(o.data);
+		signum = o.signum;
+	}
 	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();}
@@ -276,9 +286,9 @@ struct BigInt{
 	
 	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;
+		if((unsigned int)jmp >= size() * sizeof(uint64_t)){std::fill(begin(),end(),0);return *this;}
 		auto it1 = begin(); 
 		auto it2 = it1 + jmp;
 		auto beforeEnd = end() - 1;
@@ -287,8 +297,8 @@ struct BigInt{
 			*it1 |= (*(it2 + 1) >> (64 - sh));
 			++it1;++it2;
 		}
-		++it1;++it2;
 		*it1 = (*it2 << sh);
+		++it1;++it2;
 		while(it1 != end()){
 			*it1 = 0;
 			++it1;
@@ -298,9 +308,9 @@ struct BigInt{
 	
 	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;
+		if((unsigned int)jmp >= size() * sizeof(uint64_t)){std::fill(begin(),end(),0);return *this;}
 		auto it1 = rbegin(); 
 		auto it2 = it1 + jmp;
 		auto beforeRend = rend() - 1;
@@ -309,8 +319,8 @@ struct BigInt{
 			*it1 |= (*(it2 + 1) << (64 - sh));
 			++it1;++it2;
 		}
+		*it1 = (*it2 >> sh);
 		++it1;++it2;
-		*it1 = (*it2 << sh);
 		while(it1 != rend()){
 			*it1 = 0;
 			++it1;
@@ -392,9 +402,8 @@ struct BigInt{
 		auto it2 = o.rbegin();
 		while(it1 != rend() && it2 != o.rend()){
 			carry = __builtin_usubll_overflow(*it1 - carry, *it2, (unsigned long long*)(&(*it1)));
-			carry |= ((*it1 - carry) == std::numeric_limits<uint64_t>::max());
-			it1++;
-			it2++;
+			if(!carry)carry = ((*it1 - carry) == std::numeric_limits<uint64_t>::max());
+			++it1;++it2;
 		}
 		while(it1 != rend() && carry){
 			carry = __builtin_usubll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
@@ -435,7 +444,19 @@ struct BigInt{
 		}
 		return s;
 	}
-	
+	inline std::string bitString(){
+		auto it = begin();
+		std::string ret = "";
+		std::cout << size() << "; " << std::flush;
+		while(it != end()){
+			std::bitset<64> bits(*it);
+			for(unsigned int i = 0;i < 64;i++){
+				ret += chars.at(((*it) & (1ULL << (64 - i))) != 0);
+			}
+			++it;
+		}
+		return ret;
+	}
 	inline std::string toString(){
 		std::deque<char> c_str;
 		const uint64_t q = 1000000000000000000ULL;

+ 9 - 2
test.cpp

@@ -28,11 +28,18 @@ std::ostream& operator<< <char>(std::ostream& out, std::vector<char> o){
 }
 int main(){
 	xoshiro_256 gen(42);
+	for(int i = 0;i < 100;i++)gen();
 	BigInt a(gen, 2);
 	a[0] >>= 30;
-	std::cout << a.toString() << std::endl;
+	BigInt x(2);
+	std::cout << x.rawString() << std::endl;
+	x.bitshiftLeft(64);
+	//x.bitshiftRight(25);
+	std::cout << x.rawString() << std::endl;// << ", " << a.rawString() << std::endl;
+	//std::cout << a.toString() << std::endl;
 	a.bitshiftLeft(1);
-	std::cout << a.toString() << std::endl;
+	//std::cout << a.toString() << std::endl;
+	return 0;
 	for(unsigned int i = 2;true;i *= 2){
 		BigInt a(gen, i);
 		BigInt b(gen, i);