Skip to content

Commit

Permalink
Implement QofInt128.pow.
Browse files Browse the repository at this point in the history
  • Loading branch information
jralls committed Dec 4, 2014
1 parent f5c7b11 commit 9e37ad2
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 2 deletions.
19 changes: 19 additions & 0 deletions src/libqof/qof/qofint128.cpp
Expand Up @@ -173,6 +173,25 @@ QofInt128::lcm(const QofInt128& b) const noexcept
return *this / common * b;
}

/* Knuth section 4.6.3 */
QofInt128
QofInt128::pow(uint b) const noexcept
{
if (isZero() || (m_lo == 1 && m_hi == 0) || isNan() || isOverflow())
return *this;
if (b == 0)
return QofInt128 (1);
QofInt128 retval (1), squares = *this;
while (b && !retval.isOverflow())
{
if (b & 1)
retval *= squares;
squares *= squares;
b >>= 1;
}
return retval;
}

bool
QofInt128::isNeg () const noexcept
{
Expand Down
6 changes: 4 additions & 2 deletions src/libqof/qof/qofint128.hpp
Expand Up @@ -125,9 +125,11 @@ enum // Values for m_flags
/**
* Computes the object raised to the parameter's power
*
* @return A QofInt128; it will be NaN if the parameter is negative.
* @param b The power to raise this to. No point in taking a QofInt128, any
* value greater than 128 would overflow on any value other than 1.
* @return A QofInt128
*/
QofInt128 pow (const QofInt128& b) const noexcept;
QofInt128 pow (uint n) const noexcept;

/**
* Computes a quotient and a remainder, passed as reference parameters.
Expand Down
21 changes: 21 additions & 0 deletions src/libqof/qof/test/gtest-qofint128.cpp
Expand Up @@ -411,3 +411,24 @@ TEST(qofint128_functions, GCD)
EXPECT_EQ (one, bigger.gcd (smallest));
EXPECT_EQ (big, smaller.lcm (smallest));
}

TEST(qofint128_functions, pow)
{

int64_t sarg {INT64_C(53309)};
int64_t barg {INT64_C(4878849681579065407)};
QofInt128 little (sarg);
QofInt128 big (barg);
auto minus = -little;

EXPECT_EQ (QofInt128(1), little.pow(0));
EXPECT_EQ (QofInt128(0), QofInt128(0).pow(123));
EXPECT_EQ (big * big, big.pow(2));
EXPECT_EQ (QofInt128(UINT64_C(66326033898754),
UINT64_C(10251549987585143605)), little.pow(7));
EXPECT_EQ (QofInt128(UINT64_C(66326033898754),
UINT64_C(10251549987585143605), QofInt128::neg),
minus.pow(7));
auto over = minus.pow(9);
EXPECT_TRUE(over.isOverflow());
}

0 comments on commit 9e37ad2

Please sign in to comment.