mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-19 21:13:35 +00:00
Organic Maps sources as of 02.04.2025 (fad26bbf22ac3da75e01e62aa01e5c8e11861005)
To expand with full Organic Maps and Maps.ME commits history run: git remote add om-historic [om-historic.git repo url] git fetch --tags om-historic git replace squashed-history historic-commits
This commit is contained in:
51
base/math.cpp
Normal file
51
base/math.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "math.hpp"
|
||||
|
||||
#include <boost/integer.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
|
||||
namespace base
|
||||
{
|
||||
|
||||
template <typename Float>
|
||||
bool AlmostEqualULPs(Float x, Float y, uint32_t maxULPs)
|
||||
{
|
||||
static_assert(std::is_floating_point<Float>::value, "");
|
||||
static_assert(std::numeric_limits<Float>::is_iec559, "");
|
||||
|
||||
// Make sure maxUlps is non-negative and small enough that the
|
||||
// default NaN won't compare as equal to anything.
|
||||
ASSERT_LESS(maxULPs, 4 * 1024 * 1024, ());
|
||||
|
||||
int constexpr bits = CHAR_BIT * sizeof(Float);
|
||||
typedef typename boost::int_t<bits>::exact IntType;
|
||||
typedef typename boost::uint_t<bits>::exact UIntType;
|
||||
|
||||
// Same as *reinterpret_cast<IntType const *>(&x), but without warnings.
|
||||
IntType xInt, yInt;
|
||||
static_assert(sizeof(xInt) == sizeof(x), "bit_cast impossible");
|
||||
std::memcpy(&xInt, &x, sizeof(x));
|
||||
std::memcpy(&yInt, &y, sizeof(y));
|
||||
|
||||
// Make xInt and yInt lexicographically ordered as a twos-complement int.
|
||||
IntType const highestBit = IntType(1) << (bits - 1);
|
||||
if (xInt < 0)
|
||||
xInt = highestBit - xInt;
|
||||
if (yInt < 0)
|
||||
yInt = highestBit - yInt;
|
||||
|
||||
// Calculate diff with special case to avoid IntType overflow.
|
||||
UIntType diff;
|
||||
if ((xInt >= 0) == (yInt >= 0))
|
||||
diff = Abs(xInt - yInt);
|
||||
else
|
||||
diff = UIntType(Abs(xInt)) + UIntType(Abs(yInt));
|
||||
|
||||
return diff <= maxULPs;
|
||||
}
|
||||
|
||||
template bool AlmostEqualULPs<float>(float x, float y, uint32_t maxULPs);
|
||||
template bool AlmostEqualULPs<double>(double x, double y, uint32_t maxULPs);
|
||||
|
||||
} // namespace base
|
||||
Reference in New Issue
Block a user