fix multiple of float number

This commit is contained in:
dhmemi 2023-11-14 07:05:28 +00:00
parent 7d84d546f9
commit d315908ecc
2 changed files with 29 additions and 19 deletions

View File

@ -863,9 +863,14 @@ class numeric : public schema
// multipleOf - if the remainder of the division is 0 -> OK
bool violates_multiple_of(T x) const
{
auto multiple = x / multipleOf_.second;
auto error = std::abs((multiple - std::round(multiple)) * multipleOf_.second);
return error > std::numeric_limits<T>::epsilon();
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);
}
void validate(const json::json_pointer &ptr, const json &instance, json_patch &, error_handler &e) const override

View File

@ -1,27 +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)
{
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);
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 expect_exception = 2;
try {
json_validator({{"type", "number"}, {"multipleOf", 0.001}}).validate(0.3 - 0.2005);
} catch (const std::exception &ex) {
expect_exception--;
}
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);
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;
return exc_count;
}