mawinkle před 6 roky
rodič
revize
7d5f4dfe26
3 změnil soubory, kde provedl 42 přidání a 3 odebrání
  1. 32 1
      include/crypt/BigInt64.hpp
  2. 5 2
      include/crypt/intrin.hpp
  3. 5 0
      test.cpp

+ 32 - 1
include/crypt/BigInt64.hpp

@@ -12,6 +12,7 @@
 #include <vector>
 #include <string>
 #include <bitset>
+#include <array>
 #include <iostream>
 #include "intrin.hpp"
 #ifdef min
@@ -20,13 +21,21 @@
 #ifdef max
 #undef max
 #endif
-const static std::vector<char> chars = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+constexpr static std::array<char, 16> chars = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
 template<typename T>
 inline int signum(T t){
 	if(t < 0)return -1;
 	if(t >= 0)return 1;
 	assert(false);
 }
+inline void singleHex(char dest[], uint64_t nr){
+	uint64_t mask = 0xf000000000000000;
+	for(unsigned int i = 0;i < 16;i++){
+		dest[i] = chars[(nr & mask) >> (4 * (15 - i))];
+		mask >>= 4;
+	}
+	dest[16] = 0;
+}
 struct BigInt{
 	
 	using lui = ::uint_128bit;
@@ -681,6 +690,27 @@ struct BigInt{
 		}
 		return ret;
 	}
+	inline std::string hexString()const{
+		auto it = begin();
+		bool flag = false;
+		std::string ret = "";
+		while(it != end()){
+			uint64_t curr(*it);
+			if(curr == 0)continue;
+			char ccurr[17];
+			singleHex(ccurr, curr);
+			if(flag){
+				ret += ccurr;
+				continue;
+			}
+			flag = true;
+			size_t start = 0;
+			while(ccurr[start] == '0')++start;
+			ret += (char*)(ccurr + start);
+			++it;
+		}
+		return ret;
+	}
 	inline std::string toString()const{
 		if(isZero())return std::to_string(0);
 		std::deque<char> c_str;
@@ -708,6 +738,7 @@ struct BigInt{
 		if(isZero())return std::to_string(0);
 		if(base == 2)return bitString();
 		if(base == 10)return toString();
+		if(base == 16)return hexString();
 		std::vector<char> c_str;
 		c_str.reserve(size() * (unsigned int)(64.0 * std::log(2) / std::log((double)base)));
 		BigInt diver = *this;

+ 5 - 2
include/crypt/intrin.hpp

@@ -44,8 +44,7 @@ inline unsigned long long mulx_u64(unsigned long long a, unsigned long long b, u
 	*hi = (unsigned long long)(r >> 64);
 	return r;
 }
-#endif
-#ifdef _MSC_VER
+#elif defined(_MSC_VER)
 #include <intrin.h>
 inline int _leading_zeros(unsigned long long x){
 	int index = 0;
@@ -67,5 +66,9 @@ bool _sbc_u64(unsigned long long a,unsigned long long b,unsigned long long* c){
 inline unsigned long long mulx_u64(unsigned long long a, unsigned long long b, unsigned long long* hi){
 	return _mulx_u64(a,b,hi);
 }
+#else
+
+#error Your compiler is neither GNU nor Clang nor MSVC
+
 #endif
 #endif //INTRIN_HPP

+ 5 - 0
test.cpp

@@ -0,0 +1,5 @@
+#include <crypt/BigInt64.hpp>
+int main(){
+	BigInt n(324236528734ULL);
+	std::cout << n.hexString() << "\n";
+}