Skip to content

Commit

Permalink
Fix ilog2 test on i386
Browse files Browse the repository at this point in the history
Use std::log2(x) instead of std::log(x)/std::log(2.0) for improved accuracy.
  • Loading branch information
kimwalisch committed Nov 12, 2017
1 parent 563b324 commit a1d3a3b
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 11 deletions.
2 changes: 1 addition & 1 deletion include/primesieve/pmath.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ inline T ilog2(T x)
T one = 1;
T log2 = 0;

for (T i = bits / 2; i != 0; i /= 2)
for (T i = bits / 2; i > 0; i /= 2)
{
if (x >= (one << i))
{
Expand Down
16 changes: 6 additions & 10 deletions test/ilog2.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
///
/// @file ilog2.cpp
/// @brief Test integer log2 function.
/// @brief Test ilog2(x) function.
/// Note that the log2(x) function from <cmath> is not
/// accurate enough near 2^64.
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
Expand All @@ -18,12 +20,6 @@
using namespace std;
using namespace primesieve;

uint64_t log2_cmath(uint64_t n)
{
double x = (double) n;
return (uint64_t) (log(x) / log(2.0));
}

void check(bool OK)
{
cout << " " << (OK ? "OK" : "ERROR") << "\n";
Expand All @@ -40,20 +36,20 @@ int main()
for (n = 1; n < 100000; n++)
{
res1 = ilog2(n);
res2 = log2_cmath(n);
res2 = (uint64_t) log2(n);
cout << "ilog2(" << n << ") = " << res1;
check(res1 == res2);
}

n = (1ull << 32) - 1;
res1 = ilog2(n);
res2 = log2_cmath(n);
res2 = (uint64_t) log2(n);
cout << "ilog2(" << n << ") = " << res1;
check(res1 == (uint64_t) res2);

n = 1ull << 32;
res1 = ilog2(n);
res2 = log2_cmath(n);
res2 = (uint64_t) log2(n);
cout << "ilog2(" << n << ") = " << res1;
check(res1 == (uint64_t) res2);

Expand Down

0 comments on commit a1d3a3b

Please sign in to comment.