Skip to content

Commit

Permalink
fix: validate multipleOf fails on float-point value (#295)
Browse files Browse the repository at this point in the history
* fix: validate multipleOf fails on float-point value

* make clang-tidy happy.

* fix test case error when multipleOf is float but number is int

* fix multiple of float number
  • Loading branch information
dhmemi authored Nov 20, 2023
1 parent c6fefb8 commit e3aa397
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ cmake-build-*
venv
env
compile_commands.json
.vs/*
5 changes: 5 additions & 0 deletions src/json-validator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,12 @@ class numeric : public schema
bool violates_multiple_of(T x) const
{
double res = std::remainder(x, multipleOf_.second);
double multiple = std::fabs(x / multipleOf_.second);
if (multiple > 1) {
res = res / multiple;
}
double eps = std::nextafter(x, 0) - static_cast<double>(x);

return std::fabs(res) > std::fabs(eps);
}

Expand Down
4 changes: 4 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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/)
Expand Down
32 changes: 32 additions & 0 deletions test/issue-293.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "nlohmann/json-schema.hpp"

using nlohmann::json_schema::json_validator;

template <typename T>
int should_throw(const nlohmann::json &schema, T value)
{
try {
json_validator(schema).validate(value);
} catch (const std::exception &ex) {
return 0;
}
return 1;
}

int main(void)
{

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);
json_validator({{"type", "number"}, {"multipleOf", 0.001}}).validate(0.030999999999999993);
json_validator({{"type", "number"}, {"multipleOf", 0.100000}}).validate(1.9);
json_validator({{"type", "number"}, {"multipleOf", 100000.1}}).validate(9000009);

int exc_count = 0;
exc_count += should_throw({{"type", "number"}, {"multipleOf", 0.001}}, 0.3 - 0.2005);
exc_count += should_throw({{"type", "number"}, {"multipleOf", 1000.02}}, (1000.03 - 0.02) * 15.0);
exc_count += should_throw({{"type", "number"}, {"multipleOf", 100000.11}}, 9000009);

return exc_count;
}

0 comments on commit e3aa397

Please sign in to comment.