add getInt64

dev
MITSUNARI Shigeo 9 years ago
parent 6a8c24f809
commit 9485c39fd2
  1. 67
      include/mcl/fp.hpp

@ -44,6 +44,21 @@ bool strToMpzArray(size_t *pBitSize, Unit *y, size_t maxBitSize, mpz_class& x, c
void copyAndMask(Unit *y, const void *x, size_t xByteSize, const Op& op, bool doMask);
inline bool isInUint64(uint64_t *pv, const fp::Block& b)
{
assert(fp::UnitBitSize == 32 || fp::UnitBitSize == 64);
const size_t start = 64 / fp::UnitBitSize;
for (size_t i = start; i < b.n; i++) {
if (b.p[i]) return false;
}
#if CYBOZU_OS_BIT == 32
*pv = b.p[0] | (uint64_t(b.p[1]) << 32);
#else
*pv = b.p[0];
#endif
return true;
}
} // mcl::fp
template<class tag = fp::TagDefault, size_t maxBitSize = MCL_MAX_OP_BIT_SIZE>
@ -332,28 +347,42 @@ public:
{
fp::Block b;
getBlock(b);
#if CYBOZU_OS_BIT == 32
const size_t start = 2;
#else
const size_t start = 1;
#endif
for (size_t i = start; i < b.n; i++) {
if (b.p[i]) {
if (pb) {
*pb = false;
return 0;
uint64_t v;
if (fp::isInUint64(&v, b)) {
if (pb) *pb = true;
return v;
}
if (!pb) throw cybozu::Exception("fpT::getUint64:large value") << *this;
*pb = false;
return 0;
}
int64_t getInt64(bool *pb = 0) const
{
fp::Block b;
getBlock(b);
bool isNegative = false;
if (fp::isGreaterArray(b.p, op_.half, op_.N)) {
op_.neg(b.p, b.p);
isNegative = true;
}
uint64_t v;
if (fp::isInUint64(&v, b)) {
const uint64_t c = uint64_t(1) << 63;
if (isNegative) {
if (v >= c) {
if (pb) *pb = true;
return int64_t(-v);
}
} else {
if (v < c) {
if (pb) *pb = true;
return int64_t(v);
}
throw cybozu::Exception("fpT::getUint64:large value") << *this;
}
}
if (pb) {
*pb = true;
}
#if CYBOZU_OS_BIT == 32
return b.p[0] | (uint64_t(b.p[1]) << 32);
#else
return b.p[0];
#endif
if (!pb) throw cybozu::Exception("fpT::getInt64:large value") << *this;
*pb = false;
return 0;
}
static inline size_t getModBitLen() { return op_.bitSize; }
bool operator==(const FpT& rhs) const { return fp::isEqualArray(v_, rhs.v_, op_.N); }

Loading…
Cancel
Save