|
@@ -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;
|