fix: validate multipleOf fails on float-point value
This commit is contained in:
parent
848bf758c7
commit
a19d71ddcb
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@ cmake-build-*
|
||||
venv
|
||||
env
|
||||
compile_commands.json
|
||||
.vs/*
|
||||
|
||||
@ -863,9 +863,13 @@ class numeric : public schema
|
||||
// multipleOf - if the remainder of the division is 0 -> OK
|
||||
bool violates_multiple_of(T x) const
|
||||
{
|
||||
double res = std::remainder(x, multipleOf_.second);
|
||||
double eps = std::nextafter(x, 0) - static_cast<double>(x);
|
||||
return std::fabs(res) > std::fabs(eps);
|
||||
if constexpr (std::is_floating_point_v<T>) {
|
||||
auto multiple = x / multipleOf_.second;
|
||||
auto error = std::abs((multiple - std::round(multiple)) * multipleOf_.second);
|
||||
return error > std::numeric_limits<T>::epsilon();
|
||||
} else {
|
||||
return x % static_cast<T>(multipleOf_.second) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
void validate(const json::json_pointer &ptr, const json &instance, json_patch &, error_handler &e) const override
|
||||
|
||||
@ -43,6 +43,10 @@ add_executable(issue-98 issue-98.cpp)
|
||||
target_link_libraries(issue-98 nlohmann_json_schema_validator)
|
||||
add_test(NAME issue-98-erase-exception-unknown-keywords COMMAND issue-98)
|
||||
|
||||
add_executable(issue-293 issue-293.cpp)
|
||||
target_link_libraries(issue-293 nlohmann_json_schema_validator)
|
||||
add_test(NAME issue-293-float-point-error COMMAND issue-293)
|
||||
|
||||
# Unit test for string format checks
|
||||
add_executable(string-format-check-test string-format-check-test.cpp)
|
||||
target_include_directories(string-format-check-test PRIVATE ${PROJECT_SOURCE_DIR}/src/)
|
||||
|
||||
27
test/issue-293.cpp
Normal file
27
test/issue-293.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "nlohmann/json-schema.hpp"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
using nlohmann::json_schema::json_validator;
|
||||
|
||||
json_validator({{"type", "number"}, {"multipleOf", 0.001}}).validate(0.3 - 0.2);
|
||||
|
||||
json_validator({{"type", "number"}, {"multipleOf", 3.3}}).validate(8.0 - 1.4);
|
||||
|
||||
json_validator({{"type", "number"}, {"multipleOf", 1000.01}}).validate((1000.03 - 0.02) * 15.0);
|
||||
|
||||
int expect_exception = 2;
|
||||
try {
|
||||
json_validator({{"type", "number"}, {"multipleOf", 0.001}}).validate(0.3 - 0.2005);
|
||||
} catch (const std::exception &ex) {
|
||||
expect_exception--;
|
||||
}
|
||||
|
||||
try {
|
||||
json_validator({{"type", "number"}, {"multipleOf", 1000.02}}).validate((1000.03 - 0.02) * 15.0);
|
||||
} catch (const std::exception &ex) {
|
||||
expect_exception--;
|
||||
}
|
||||
|
||||
return expect_exception;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user