Fix comparision of two doubles

One of multipleOf test failed because most floating-point numbers end
up being slightly imprecise. And, the check of multipleOf with two
double numbers using the dividend (a) and the result of multiplying
the multiple after rounding down by the divisor (floor(|a|/|b|)*b) to
compare.

Change to using std::numeric_limits::epsilon to check the error of
the division result.
This commit is contained in:
Esther Wang 2023-12-12 15:48:41 +08:00 committed by Milo Yip
parent 060a09a1c5
commit 5a74efa8c7
1 changed files with 7 additions and 3 deletions

View File

@ -1641,9 +1641,13 @@ private:
bool CheckDoubleMultipleOf(Context& context, double d) const {
double a = std::abs(d), b = std::abs(multipleOf_.GetDouble());
double q = std::floor(a / b);
double r = a - q * b;
if (r > 0.0) {
double q = a / b;
double qRounded = std::floor(q + 0.5);
double scaledEpsilon = (q + qRounded) * std::numeric_limits<double>::epsilon();
double difference = std::abs(qRounded - q);
bool isMultiple = (difference <= scaledEpsilon)
|| (difference < std::numeric_limits<double>::min());
if (!isMultiple) {
context.error_handler.NotMultipleOf(d, multipleOf_);
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMultipleOf);
}