|
@@ -2,6 +2,7 @@
|
|
#define BIG_INT_HPP
|
|
#define BIG_INT_HPP
|
|
#include "semi_bitset.hpp"
|
|
#include "semi_bitset.hpp"
|
|
#include <cstdlib>
|
|
#include <cstdlib>
|
|
|
|
+#include <string>
|
|
template<size_t size>
|
|
template<size_t size>
|
|
class BigInt{
|
|
class BigInt{
|
|
private:
|
|
private:
|
|
@@ -19,8 +20,8 @@ public:
|
|
bits.data[bits.length() - 1] = o;
|
|
bits.data[bits.length() - 1] = o;
|
|
}
|
|
}
|
|
inline BigInt(long long o){
|
|
inline BigInt(long long o){
|
|
- if(o < 0){signum = -1;o *= -1;}
|
|
|
|
- bits.data[bits.length() - 1] = (lower_half);
|
|
|
|
|
|
+ if(o < 0){signum = -1;o = 0ULL - o;}
|
|
|
|
+ bits.data[bits.length() - 1] = (o & lower_half);
|
|
bits.data[bits.length() - 2] = (o >> 32);
|
|
bits.data[bits.length() - 2] = (o >> 32);
|
|
}
|
|
}
|
|
inline BigInt(unsigned long long o){
|
|
inline BigInt(unsigned long long o){
|
|
@@ -28,7 +29,7 @@ public:
|
|
bits.data[bits.length() - 2] = (o >> 32);
|
|
bits.data[bits.length() - 2] = (o >> 32);
|
|
}
|
|
}
|
|
template<std::size_t osize>
|
|
template<std::size_t osize>
|
|
- BigInt<size> add(const BigInt<osize>& o)const{
|
|
|
|
|
|
+ inline BigInt<size> add(const BigInt<osize>& o)const{
|
|
static_assert(size == osize);
|
|
static_assert(size == osize);
|
|
BigInt<size> ret;
|
|
BigInt<size> ret;
|
|
uint64_t carry = 0;
|
|
uint64_t carry = 0;
|
|
@@ -40,38 +41,71 @@ public:
|
|
}
|
|
}
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
+ template<size_t osize>
|
|
|
|
+ inline BigInt<size> mult(const BigInt<osize>& o)const{
|
|
|
|
+ BigInt<size + osize> ret;
|
|
|
|
+ uint64_t mat[size][size] = {0};
|
|
|
|
+ uint64_t carry = 0;
|
|
|
|
+ for(size_t i = 0;i < size;i++){
|
|
|
|
+ for(size_t ih = size - 1;ih != ~(0ULL);ih--){
|
|
|
|
+ mat[i][ih] = (*this)[i] * o[ih] + carry;
|
|
|
|
+ carry = mat[i][ih] >> 32;
|
|
|
|
+ mat[i][ih] &= lower_half;
|
|
|
|
+ if(ih == 0)break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ carry = 0;
|
|
|
|
+ for(size_t i = size - 1;i != ~(0ULL);i--){
|
|
|
|
+ uint64_t accum = 0;
|
|
|
|
+ for(size_t ih = 0;ih < size;ih++){
|
|
|
|
+ accum += ((i + ih) >= size) ? 0 : mat[i + ih][ih];
|
|
|
|
+ }
|
|
|
|
+ accum += carry;
|
|
|
|
+ ret[i] = accum & lower_half;
|
|
|
|
+ carry = accum >> 32;
|
|
|
|
+ }
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
|
|
- BigInt<size> div(unsigned int o)const{
|
|
|
|
|
|
+ inline BigInt<size> div(unsigned int o)const{
|
|
uint64_t carry = 0;
|
|
uint64_t carry = 0;
|
|
BigInt<size> ret;
|
|
BigInt<size> ret;
|
|
for(size_t i = 0;i < size;i++){
|
|
for(size_t i = 0;i < size;i++){
|
|
- lldiv_t dm = std::div((unsigned long long int)((carry << 32) + (*this)[i]),(unsigned long long int)o);
|
|
|
|
- carry = dm.rem;
|
|
|
|
- std::cout << " " << dm.rem << " ";
|
|
|
|
- ret[i] = dm.quot;
|
|
|
|
|
|
+ uint64_t res = ((*this)[i] + (carry << 32)) / o;
|
|
|
|
+ carry = (*this)[i] % o;
|
|
|
|
+ ret[i] = res;
|
|
}
|
|
}
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
- unsigned int mod(unsigned int o)const{
|
|
|
|
|
|
+ inline unsigned int mod(unsigned int o)const{
|
|
uint64_t carry = 0;
|
|
uint64_t carry = 0;
|
|
for(size_t i = 0;i < size;i++){
|
|
for(size_t i = 0;i < size;i++){
|
|
- lldiv_t dm = std::div((long long int)((carry << 32) + (*this)[i]),(unsigned long long int)o);
|
|
|
|
- carry = dm.rem;
|
|
|
|
|
|
+ carry = (this->operator[](i) + (carry << 32)) % o;
|
|
}
|
|
}
|
|
return (unsigned int)(carry & lower_half);
|
|
return (unsigned int)(carry & lower_half);
|
|
}
|
|
}
|
|
- std::uint64_t& operator[](size_t i){
|
|
|
|
|
|
+ inline std::uint64_t& operator[](size_t i){
|
|
return bits.data[i];
|
|
return bits.data[i];
|
|
}
|
|
}
|
|
|
|
|
|
- const std::uint64_t& operator[](size_t i)const{
|
|
|
|
|
|
+ inline const std::uint64_t& operator[](size_t i)const{
|
|
return bits.data[i];
|
|
return bits.data[i];
|
|
}
|
|
}
|
|
|
|
+ inline bool isZero()const{
|
|
|
|
+ for(size_t i = 0;i < size;i++){
|
|
|
|
+ if(this->operator[](i))return false;
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
template<typename stream, size_t osize>
|
|
template<typename stream, size_t osize>
|
|
inline friend stream& operator<<(stream& s, const BigInt<osize>& o){
|
|
inline friend stream& operator<<(stream& s, const BigInt<osize>& o){
|
|
- for(size_t i = 0;i < o.bits.length();i++)
|
|
|
|
- s << std::bitset<32>((uint32_t)(o.bits.data[i] & lower_half));
|
|
|
|
- return s;
|
|
|
|
|
|
+ std::string a = "";
|
|
|
|
+ BigInt dis = o;
|
|
|
|
+ while(!dis.isZero()){
|
|
|
|
+ a = std::to_string(dis.mod(10)) + a;
|
|
|
|
+ dis = dis.div(10);
|
|
|
|
+ }
|
|
|
|
+ return s << a;
|
|
}
|
|
}
|
|
};
|
|
};
|
|
#endif
|
|
#endif
|