Add integer square root to SCMP.
This commit is contained in:
parent
94672bba98
commit
f99d5a8356
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.22)
|
||||
project(scsl LANGUAGES CXX
|
||||
VERSION 1.1.3
|
||||
VERSION 1.1.4
|
||||
DESCRIPTION "Shimmering Clarity Standard Library")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
|
|
|
@ -115,6 +115,13 @@ WithinTolerance(T a, T b, T epsilon)
|
|||
}
|
||||
|
||||
|
||||
/// \brief Integer square-root.
|
||||
///
|
||||
/// \param n A max-value integer whose square root should be returned.
|
||||
/// \return The square root of $n$.
|
||||
size_t ISqrt(size_t n);
|
||||
|
||||
|
||||
} // namespace scmp
|
||||
|
||||
|
||||
|
|
|
@ -151,5 +151,37 @@ DefaultEpsilon(int& epsilon)
|
|||
}
|
||||
|
||||
|
||||
size_t
|
||||
ISqrt(size_t n)
|
||||
{
|
||||
if (n < 2) {
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t start = 0;
|
||||
size_t end = n / 2;
|
||||
size_t result = 0;
|
||||
|
||||
while (start <= end) {
|
||||
auto middle = (start + end) >> 1;
|
||||
result = middle * middle;
|
||||
if (result == n) {
|
||||
return middle;
|
||||
}
|
||||
|
||||
if (result < n) {
|
||||
start = middle + 1;
|
||||
result = middle;
|
||||
} else {
|
||||
end = middle - 1;
|
||||
result = middle;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace scmp
|
||||
|
||||
|
|
30
test/math.cc
30
test/math.cc
|
@ -116,6 +116,35 @@ RotateRadians()
|
|||
}
|
||||
|
||||
|
||||
bool
|
||||
IntegerSquareRoot()
|
||||
{
|
||||
static std::vector<size_t> ns{
|
||||
// standard integer roots
|
||||
4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144,
|
||||
|
||||
// a few float cases
|
||||
42, 90, 92
|
||||
};
|
||||
static std::vector<size_t> expected{
|
||||
// standard integer roots
|
||||
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
|
||||
|
||||
// a few float cases
|
||||
6, 9, 10
|
||||
};
|
||||
|
||||
SCTEST_CHECK_EQ(ns.size(), expected.size());
|
||||
|
||||
for (size_t i = 0; i < ns.size(); i++) {
|
||||
auto root = scmp::ISqrt(ns.at(i));
|
||||
SCTEST_CHECK_EQ(root, expected.at(i));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
|
@ -148,6 +177,7 @@ main(int argc, char *argv[])
|
|||
suite.AddTest("WithinToleranceFloat", WithinToleranceFloat);
|
||||
suite.AddTest("WithinToleranceDouble", WithinToleranceDouble);
|
||||
suite.AddTest("RotateRadians", RotateRadians);
|
||||
suite.AddTest("IntegerSquareRoot", IntegerSquareRoot);
|
||||
|
||||
delete flags;
|
||||
auto result = suite.Run();
|
||||
|
|
Loading…
Reference in New Issue