|
@@ -3,6 +3,7 @@
|
|
#include "semi_bitset.hpp"
|
|
#include "semi_bitset.hpp"
|
|
#include <cstdlib>
|
|
#include <cstdlib>
|
|
#include <string>
|
|
#include <string>
|
|
|
|
+#include <iostream>
|
|
template<size_t size>
|
|
template<size_t size>
|
|
class BigInt{
|
|
class BigInt{
|
|
private:
|
|
private:
|
|
@@ -42,27 +43,35 @@ public:
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
template<size_t osize>
|
|
template<size_t osize>
|
|
- inline BigInt<size> mult(const BigInt<osize>& o)const{
|
|
|
|
|
|
+ inline BigInt<size + osize> mult(const BigInt<osize>& o)const{
|
|
BigInt<size + osize> ret;
|
|
BigInt<size + osize> ret;
|
|
uint64_t mat[size][size] = {0};
|
|
uint64_t mat[size][size] = {0};
|
|
uint64_t carry = 0;
|
|
uint64_t carry = 0;
|
|
for(size_t i = 0;i < size;i++){
|
|
for(size_t i = 0;i < size;i++){
|
|
for(size_t ih = size - 1;ih != ~(0ULL);ih--){
|
|
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;
|
|
|
|
|
|
+ mat[size - i - 1][ih] = (*this)[i] * o[ih] + carry;
|
|
|
|
+ carry = mat[size - i - 1][ih] >> 32;
|
|
|
|
+ mat[size - i - 1][ih] &= lower_half;
|
|
if(ih == 0)break;
|
|
if(ih == 0)break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ for(size_t i = 0;i < size;i++){
|
|
|
|
+ for(size_t ih = 0;ih < size;ih++){
|
|
|
|
+ std::cout << mat[i][ih] << " ";
|
|
|
|
+ }
|
|
|
|
+ std::cout << std::endl;
|
|
|
|
+ }
|
|
carry = 0;
|
|
carry = 0;
|
|
- for(size_t i = size - 1;i != ~(0ULL);i--){
|
|
|
|
|
|
+ for(std::int64_t i = size - 1;i > -((std::int64_t)size);i--){
|
|
uint64_t accum = 0;
|
|
uint64_t accum = 0;
|
|
- for(size_t ih = 0;ih < size;ih++){
|
|
|
|
- accum += ((i + ih) >= size) ? 0 : mat[i + ih][ih];
|
|
|
|
|
|
+ for(std::int64_t ih = 0;ih < size;ih++){
|
|
|
|
+ accum += ((i + ih) >= size || (i + ih) < 0) ? 0 : mat[ih][i + ih];
|
|
}
|
|
}
|
|
accum += carry;
|
|
accum += carry;
|
|
- ret[i] = accum & lower_half;
|
|
|
|
|
|
+ ret[i + osize] = accum & lower_half;
|
|
|
|
+ //std::cout << accum << " ";
|
|
carry = accum >> 32;
|
|
carry = accum >> 32;
|
|
|
|
+ if(i == 0)break;
|
|
}
|
|
}
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -97,15 +106,16 @@ public:
|
|
}
|
|
}
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
- template<typename stream, size_t osize>
|
|
|
|
- inline friend stream& operator<<(stream& s, const BigInt<osize>& o){
|
|
|
|
- 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
|
|
|
|
|
|
+template<size_t osize>
|
|
|
|
+inline std::ostream& operator<<(std::ostream& s, const BigInt<osize>& o){
|
|
|
|
+ std::string a = "";
|
|
|
|
+ BigInt<osize> dis = o;
|
|
|
|
+ while(!dis.isZero()){
|
|
|
|
+ a = std::to_string(dis.mod(10)) + a;
|
|
|
|
+ dis = dis.div(10);
|
|
|
|
+ }
|
|
|
|
+ return s << a;
|
|
|
|
+}
|
|
|
|
+#endif
|