blob: 0920680364cc45264fc3aa7143c198651ddaa981 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
#include <cmath>
namespace vespalib {
/**
* Compare two double-precision floating-point numbers to see if they
* are approximately equal. We convert to floating-point and then
* step 1 unit in the last place towards the other number. This means the
* two numbers must be equal to 23 bits precision.
**/
constexpr bool approx_equal(double a, double b)
{
if (a == b) return true;
if (a > 1.0 || a < -1.0) {
// This is in a way the simple case, but it's needed
// anyway to handle numbers that are outside "float" range.
double frac = b / a;
float rounded = std::nextafterf(frac, 1.0);
return (rounded == 1.0);
}
// in reality this may allow up to 2 bits difference
// since we round to float and also call nextafterf
float aa = (float) a;
return (aa == std::nextafterf((float) b, aa));
}
} // namespace vespalib
|