存储的方式
浮点型数据在内存中的存储机制与整型数据不同,有舍入误差问题,在计算机中用近似表示任意某个实数。其表示形式是一个整数或定点数(即尾数)乘以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