以IEEE 754中规定的32位浮点数为例子,我们知道32位浮点数中1位是符号位,8位是指数位,剩下的23位是尾数位(也即二进制科学记数法小数点右边的部分)。这样一来,对于同一个数量级的两个实数,使用32位浮点数能够区分的最小分辨率是1 / (2^23),这个数大约是1.19e-7,也就是说如果使用1e-6作为epsilon,当两个浮点数的差小于1e-6时,我们大致能认为两个数相等。
来自cppreference的浮点数比较代码片段:
template<class T>
typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
almost_equal(T x, T y, int ulp = 6)
{
// the machine epsilon has to be scaled to the magnitude of the values used
// and multiplied by the desired precision in ULPs (units in the last place)
return std::abs(x-y) <= std::numeric_limits<T>::epsilon() * std::abs(x+y) * ulp
// unless the result is subnormal
|| std::abs(x-y) < std::numeric_limits<T>::min();
}