Fix silent wrong results for custom number types

Squashed onto develop cd6b428ef (CI fixes from #5860). Original commits:

- Fix silent wrong results for custom number types
- Fix CI: build the out_of_range.407 message from string_t and fix a link
- Fix CI: diagnostics message, clang-tidy, and MinGW section limit
- Format the out_of_range.407 number without dump()
- Move the std::deque array test out of unit-regression3.cpp
- Fix clang-tidy and clang 3.4/3.5 failures in the custom number type changes
- Fix CI: cast the 128-bit unsigned value explicitly in the integer fast path

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann committed 2026-10-16 19:26:47 +02:00
1 parent cd6b428ef0
commit 419e1678ee
15 files changed
+1127 -358

No files matched your search

+6 -4
View File
@@ -14,7 +14,6 @@
#include <cstdint> // uint8_t
#include <limits> // numeric_limits
#include <string> // string
#include <type_traits> // is_signed
#include <nlohmann/detail/macro_scope.hpp>
#if JSON_HAS_THREE_WAY_COMPARISON
@@ -175,13 +174,16 @@ FloatType compare_integer_with_float(const IntegerType i, const FloatType f) noe
// values of IntegerType lie in [-bound, bound) when signed and in
// [0, bound) when unsigned; digits excludes the sign bit, so bound is a
// power of two that the float represents exactly
const FloatType bound = std::ldexp(static_cast<FloatType>(1), std::numeric_limits<IntegerType>::digits);
// power of two that the float represents exactly; the signedness comes
// from numeric_limits as well, because std::is_signed is false for class
// types such as 128-bit or multiprecision integers
using limits = std::numeric_limits<IntegerType>;
const FloatType bound = std::ldexp(static_cast<FloatType>(1), limits::digits);
if (f >= bound)
{
return ordered(-1);
}
if (std::is_signed<IntegerType>::value ? (f < -bound) : (f < static_cast<FloatType>(0)))
if (limits::is_signed ? (f < -bound) : (f < static_cast<FloatType>(0)))
{
return ordered(1);
}