浮点型数据的比较

存储的方式
浮点型数据在内存中的存储机制与整型数据不同,有舍入误差问题,在计算机中用近似表示任意某个实数。其表示形式是一个整数或定点数(即尾数)乘以2的整数次幂的到,类似基于10的科学计数法。
精度问题
float类型小数点前后加起来有效数字只有6位,当给定的float有效数在6位以内转换为字符串时不会丢失精度,否则将存在精度丢失问题。
double类型小数店前后加起来有效数字只有16位,当给定的double有效数在16位以内转换成字符串时,不会造成精度丢失,否则将存在京都丢失问题。
数值的比较
两个整型数据可以直接通过 "==" 号来比较,浮点型却不行,这样的处理结果返回值是完全不确定的,因此我们需要通过一种方法来使我们认为两个浮点数相等,例如以下的代码

const float EPSINON = 0.00001;
// double型可以设定EPSINON=0.00000001;
if (abs(fA-fB)<=EPSINON) {
    // fA与fB相等
}
else {
    // fA与fB不相等
}

另一种比较方案

// from http://en.cppreference.com/w/cpp/types/numeric_limits/epsilon
typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
    almost_equal(T x, T y, int ulp)
{
    // 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();
}
int main()
{
    double d1 = 0.2;
    double d2 = 1 / std::sqrt(5) / std::sqrt(5);
 
    if(d1 == d2)
            std::cout << "d1 == d2\n";
    else
            std::cout << "d1 != d2\n";
 
    if(almost_equal(d1, d2, 2))
            std::cout << "d1 almost equals d2\n";
    else
            std::cout << "d1 does not almost equal d2\n";
}

以上代码执行结果是

d1 != d2
d1 almost equals d2
posted @ 2016-05-20 20:27  KAME  阅读(1376)  评论(0编辑  收藏  举报