Add integer square root to SCMP.

This commit is contained in:
Kyle Isom 2023-11-09 00:38:01 -08:00
parent 94672bba98
commit f99d5a8356
4 changed files with 70 additions and 1 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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();