为什么比较double和float会导致意想不到的结果?
可能重复:
浮点数与浮点数相比,奇怪的输出
float f = 1.1; double d = 1.1; if(f == d) // returns false! 为什么这样?
  float或double数考虑的重要因素是: 
  精确度和舍入 
  精确: 
  浮点数的精度是它可以表示多less位数,而不会丢失它所包含的任何信息。 
 考虑分数1/3 。 这个数字的十进制表示是0.33333333333333… 3的无限远。 一个无限长度的数字将需要以精确的精度来描述无限的内存,但是float或者double数据types通常只有4或者8个字节。 因此,浮点数和双数只能存储一定数量的数字,其余的数字一定会丢失。 因此,没有确切的方法来表示浮点数或双精度数的数字,这些精度要比variables能保持的精度要高。 
  四舍五入: 
  binary和decimal (base 10)数字之间有一个非明显的差异。 
 考虑1/10分数。 在decimal ,这可以很容易地表示为0.1可以被认为是一个容易表示的数字。 但是,在二进制中, 0.1由无限序列表示: 0.00011001100110011… 
一个例子:
 #include <iomanip> int main() { using namespace std; cout << setprecision(17); double dValue = 0.1; cout << dValue << endl; } 
这个输出是:
 0.10000000000000001 
并不是
 0.1. 
 这是因为double由于内存有限而不得不截断近似值,导致一个不完全0.1 。 这种情况被称为舍入错误 。 
 每当比较两个closures的浮点数和双精度数时,这样的舍入误差就会引入,最终导致比较结果不正确,这就是您不应该使用==比较浮点数或双精度浮点数的原因。 
你可以做的最好的是采取他们的差异,并检查它是否小于一个epsilon。
 abs(x - y) < epsilon 
尝试运行这个代码,结果会使原因显而易见。
 #include <iomanip> #include <iostream> int main() { std::cout << std::setprecision(100) << (double)1.1 << std::endl; std::cout << std::setprecision(100) << (float)1.1 << std::endl; std::cout << std::setprecision(100) << (double)((float)1.1) << std::endl; } 
输出:
 1.100000000000000088817841970012523233890533447265625 1.10000002384185791015625 1.10000002384185791015625 
 无论是float还是double都不能准确表示1.1。 当您尝试进行比较时,浮点数被隐式上转换为double。  double数据types可以准确地表示float的内容,所以比较结果是错误的。 
 一般来说,你不应该比较漂浮物浮动,双打双打或漂浮使用==双打。 
最好的做法是减去它们,并检查差异的绝对值是否小于一个小的epsilon。
 if(std::fabs(f - d) < std::numeric_limits<float>::epsilon()) { // ... } 
一个原因是因为浮点数是(或多或less)二进制分数,并且只能接近许多十进制数。 许多十进制数字必须转换为重复二进制“小数”,或无理数字。 这将引入舍入错误。
从维基百科 :
例如,1/5不能完全表示为使用二进制基数的浮点数,但可以使用十进制基数精确表示。
 在你的具体情况下,浮点数和双精度对不合理/重复部分的舍入是不同的,必须用二进制表示1.1 。 在相应的转换引入了不同级别的舍入误差之后,你将很难让它们“相等”。 
我上面给出的代码通过简单地检查这些值是否在很短的三angular洲内解决了这个问题。 你的比较从“这些值是否相等? 到“这些值是否在相互之间的一个小误差范围之内?
另外,看到这个问题: 什么是最有效的方式进行浮点和双重比较?
还有很多关于浮点数的其他奇怪的事情,这些奇怪的事情都会打破简单的平等比较。 检查这篇文章的一些他们的描述:
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
  IEEE 754 32位float可以存储: 1.1000000238... 
  IEEE 754 64位double可以存储: 1.1000000000000000888... 
看看他们为什么不是“平等的”?
在IEEE 754中,分数存储在2:
 2^(-1), 2^(-2), 2^(-3), ... 1/2, 1/4, 1/8, ... 
 现在我们需要一种方法来表示0.1 。 这是32位IEEE 754表示(浮点)的(简化版本): 
 2^(-4) + 2^(-5) + 2^(-8) + 2^(-9) + 2^(-12) + 2^(-13) + ... + 2^(-24) + 2^(-25) + 2^(-27) 00011001100110011001101 1.10000002384185791015625 
 使用64位double精度,就更加精确。 它不会停在2^(-25) ,它会持续两倍左右。  ( 2^(-48) + 2^(-49) + 2^(-51) ,也许?) 
资源
IEEE 754转换器 (32位)
浮点数和双精度数以二进制格式存储,不能准确地表示每个数字(在有限空间中无法表示无限多个可能的不同数字)。
结果他们四舍五入。 浮点数要翻一倍以上,因为它比较小,所以1.1舍入到最近的有效浮点数不同于1.1舍入到最近的valud Double。
要查看哪些数字是有效的浮点数和双精度浮点数