mawinkle пре 6 година
родитељ
комит
d91200f027
3 измењених фајлова са 46 додато и 23 уклоњено
  1. 18 18
      crypt/BigInt64.hpp
  2. 26 0
      crypt/intrin.hpp
  3. 2 5
      test.cpp

+ 18 - 18
crypt/BigInt64.hpp

@@ -13,13 +13,13 @@
 #include <string>
 #include <bitset>
 #include <iostream>
-const std::vector<char> chars = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
-const __uint128_t _m = ((__uint128_t)1) << 64;
-std::uint64_t _mulx_u64(std::uint64_t a, std::uint64_t b, std::uint64_t* hi){
-	__uint128_t r = a * b;
-	*hi = (r >> 64);
+#include "intrin.hpp"
+const static std::vector<char> chars = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+/*std::uint64_t _mulx_u64(std::uint64_t a, std::uint64_t b, std::uint64_t* hi){
+	__uint128_t r = ((__uint128_t)a) * b;
+	*hi = (std::uint64_t)(r >> 64);
 	return r;
-}
+}*/
 template<typename T>
 inline int signum(T t){
 	if(t < 0)return -1;
@@ -103,7 +103,7 @@ struct BigInt{
 			s += 64;
 		}
 		if(it == end())return s + 64;
-		return s + __builtin_clzll(*it);
+		return s + _leading_zeros(*it);
 	}
 	inline size_t bitscanReverse()const{
 		auto it = rbegin();
@@ -113,7 +113,7 @@ struct BigInt{
 			s += 64;
 		}
 		if(it == rend())return s + 64;
-		return s + __builtin_ctzll(*it);
+		return s + _trailing_zeros(*it);
 	}
 	
 	inline bool operator<(const BigInt& o)const{
@@ -465,7 +465,7 @@ struct BigInt{
 			if(*it1 == 0)
 				pos1 += 64;
 			else{
-				pos1 += __builtin_clzll(*it1);
+				pos1 += _leading_zeros(*it1);
 				bitfound = true;
 				break;
 			}
@@ -477,7 +477,7 @@ struct BigInt{
 			if(*it2 == 0)
 				pos2 += 64;
 			else{
-				pos2 += __builtin_clzll(*it2);
+				pos2 += _leading_zeros(*it2);
 				bitfound = true;
 				break;
 			}
@@ -542,13 +542,13 @@ struct BigInt{
 		auto it1 = rbegin();
 		auto it2 = o.rbegin();
 		while(it1 != rend() && it2 != o.rend()){
-			carry = __builtin_uaddll_overflow(*it1, *it2 + carry, (unsigned long long*)(&(*it1)));
+			carry = _adc_u64(*it1, *it2 + carry, (unsigned long long*)(&(*it1)));
 			carry |= (*it2 + carry) == 0 && *it2;
 			++it1;
 			++it2;
 		}
 		while(it1 != rend() && carry){
-			carry = __builtin_uaddll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
+			carry = _adc_u64(*it1, carry, (unsigned long long*)(&(*it1)));
 			++it1;
 		}
 		if(carry)data.push_front(1);
@@ -560,12 +560,12 @@ struct BigInt{
 		auto it1 = rbegin();
 		auto it2 = o.rbegin();
 		while(it1 != rend() && it2 != o.rend()){
-			carry = __builtin_usubll_overflow(*it1 - carry, *it2, (unsigned long long*)(&(*it1)));
+			carry = _sbc_u64(*it1 - carry, *it2, (unsigned long long*)(&(*it1)));
 			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)));
+			carry = _sbc_u64(*it1, carry, (unsigned long long*)(&(*it1)));
 			++it1;
 		}
 		return *this;
@@ -616,7 +616,7 @@ struct BigInt{
 			if(o == 1){t = t.mult(odd);t.moda(mod);return t;}
 		}
 	}
-	inline BigInt multNew(const BigInt& o)const{
+	inline BigInt mult(const BigInt& o)const{
 		BigInt result(size() + o.size() + 1,0);
 		BigInt temp(size() + o.size() + 1,0);
 		int p = 0;
@@ -625,8 +625,8 @@ struct BigInt{
 			uint64_t carry = 0;
 			for(auto it2 = o.rbegin();it2 != o.rend();it2++){
 				uint64_t hi;
-				uint64_t lo = _mulx_u64(*it1, *it2, &hi);
-				bool ac = __builtin_uaddll_overflow(lo, carry, (unsigned long long*)(&(*(it++))));
+				uint64_t lo = _mulx_u64(*it1, *it2, (unsigned long long*)&hi);
+				bool ac = _adc_u64(lo, carry, (unsigned long long*)(&(*(it++))));
 				carry = hi + ac;
 			}
 			if(carry)(*it) += carry;
@@ -638,7 +638,7 @@ struct BigInt{
 		return result;
 	}
 	
-	inline BigInt mult(const BigInt& o)const{
+	inline BigInt multOld(const BigInt& o)const{
 		BigInt result(size() + o.size() + 1,0);
 		BigInt temp(size() + o.size() + 1,0);
 		int p = 0;

+ 26 - 0
crypt/intrin.hpp

@@ -0,0 +1,26 @@
+#ifndef INTRIN_HPP
+#define INTRIN_HPP
+#include <cstdint>
+#if defined(__GNUC__) || defined(__clang__)
+inline int _leading_zeros(unsigned long long x){
+	return __builtin_clzll(x);
+}
+inline int _trailing_zeros(unsigned long long x){
+	return __builtin_ctzll(x);
+}
+bool _adc_u64(unsigned long long a,unsigned long long b,unsigned long long* c){
+	return __builtin_uaddll_overflow(a, b, c);
+}
+bool _sbc_u64(unsigned long long a,unsigned long long b,unsigned long long* c){
+	 return __builtin_usubll_overflow(a, b, c);
+}
+inline unsigned long long _mulx_u64(unsigned long long a, unsigned long long b, unsigned long long* hi){
+	__uint128_t r = ((__uint128_t)a) * b;
+	*hi = (unsigned long long)(r >> 64);
+	return r;
+}
+#endif
+#ifdef _WIN64
+
+#endif
+#endif //INTRIN_HPP

+ 2 - 5
test.cpp

@@ -50,11 +50,8 @@ unsigned long long multTest(size_t s){
 	return std::accumulate(times.begin(), times.end(), 0ULL);
 }
 int main(){
-	BigInt a(1000000000000ULL);
-	BigInt b(1000000000000ULL);
-	a = a.multNew(b);
-	std::cout << a.toString() << std::endl;
-	return 0;
+	BigInt a(~(0ULL)),b(~(0ULL));
+	std::cout << a.mult(b).toString() << std::endl;
 	multTest(50);
 	multTest(100);
 	multTest(200);