Comparison of float and double variables
Possible Duplicates:
Difference between float and double
strange output in comparision of float with float literal
我使用Visual C++ 6,在一个程序中,我比较浮点和双变量。例如,对于这个程序
1 2 3 4 5 6 7 8
| #include<stdio.h>
int main ()
{
float a = 0.7f;
double b = 0.7;
printf("%d %d %d",a <b ,a >b ,a ==b );
return 0;
} |
我的输出是1 0 0
为了
1 2 3 4 5 6 7 8
| #include<stdio.h>
int main ()
{
float a = 1.7f;
double b = 1.7;
printf("%d %d %d",a <b ,a >b ,a ==b );
return 0;
} |
我得到0 1 0作为输出。
请告诉我为什么我得到这些奇怪的输出,有没有任何方法可以预测这些输出在同一个处理器上。另外,如何比较C中的两个变量?
- 您不应该为了相等而比较浮点值-由于已知的精度和舍入问题,结果是不可预测的。这是许多帖子的副本-很快就会找到一个。
- 成百上千的"浮点数被破坏了吗?"问题。。。读这些直到你知道浮点数天生不准确。
- 尝试比较双打和彩车会导致疼痛,沮丧,心碎,可能是疯狂。
- @德尔南:我不认为浮点数本身就是不准确的。我将把十进制值到二进制浮点值的转换描述为固有损耗。
- 相关stackoverflow.com/questions/2743718/when is aa true/&hellip;:)
- @乔恩·斯基特:是的,有很多数字可以用浮点数来表示。可悲的是,有无限多的理性,当你摆弄浮动的时候,你几乎可以保证碰到那些(即不连续的)。因此,最好将浮动视为始终不准确,并将100%准确的结果视为异常:)
- @德尔南:你认为整数也不准确吗?毕竟,它们不能代表所有的数字。把5除以2,你会得到2的整数算术,而不是2.5-但是没有人说整数是不准确的,他们只是理解一组可能的值。我相信,鼓励二元浮点值的理解水平,比在没有限定的情况下将"不准确"一词带到周围要好。(也出于兴趣:您是否认为十进制浮点类型(如.NET中的System.Decimal)是"不准确的"?)
- @乔恩·斯基特:我同意人们应该理解浮动是如何工作的。浮点数(包括小数)不是实数,只是它的一个近似值——所以当把它们当作实数时,至少要记住这在实践中意味着什么:不准确(小数也不准确)——但是使用人类习惯的基数,所以不准确不是那么意外-1/3不能用以10为基数的有限位数表示,"但没关系,我们将一如既往地进行四舍五入"。
- @德尔南:我不同意。我将浮点和小数视为具有精确的值,这可能只是产生它们的计算的精确结果的近似值。1.5就是1.5,就像1就是1。仅仅因为6/5不完全是1就不会使数字1的精确性降低。同样,你相信整数不是实数,只是近似数吗?
- @乔恩·斯基特:是的,1.5就是1.5,123.4567891213E-50就是123.4567891213E-50。但后者可能是计算的结果,在"真实数学"中,结果略有不同,因为实际结果不能用这种浮点格式表示。整数是精确的-根据定义,它们保持在整数域内,并且可以表示其范围内的每个整数(浮点到实数域,但不能表示每个实数)。但也许我们现在应该停止让这个问题继续存在:)
- @Delnan:但是当以整数(例如5/2)表示时,涉及整数的计算结果也可能不准确。我同意整数可以覆盖其范围内的每个值,但我不认为这是"准确"和"不准确"之间的有效区别。我敢说,你可以沿着这些线提出一个精确的定义,但如果没有这个定义,我相信声称浮点数是"不准确的"是太含糊,特别有用。任何特定的浮点值都是实数的精确表示(续)
- 这个实数很容易确定。是的,有无限多的其他实数将被四舍五入到相同的浮点值-但这就是为什么我认为操作(转换等)不准确-或至少"有损性"-而不是值本身不准确。
它与计算机中浮点和双精度数的内部表示方式有关。计算机以2为基数的二进制存储数字。以二进制形式存储时,以10为基数的数字可能有重复的数字,并且计算机中存储的"精确"值不相同。
比较浮点数时,通常使用epsilon来表示值的微小变化。例如:
1 2 3 4 5 6
| float epsilon = 0.000000001;
float a = 0.7;
double b = 0.7;
if (abs(a - b ) < epsilon )
// they are close enough to be equal. |
1.7d和1.7f很可能是不同的值:一个是在双表示中最接近绝对值1.7,另一个是在浮点表示中最接近绝对值1.7。
为了更简单地理解术语,假设您有两种类型,shortDecimal和longDecimal。shortDecimal是一个具有3个有效数字的十进制值。longDecimal是一个具有5个有效数字的十进制值。现在假设您有某种方法来表示程序中的pi,并将值赋给shortDecimal和longDecimal变量。短值为3.14,长值为3.1416。这两个值并不相同,尽管它们都是各自类型中最接近pi的可表示值。
- 他在传递整数。
- @汉斯:发帖后问题变了。它最初是打印a和b(几乎;实际上是ab,我认为这是a,b的一个拼写错误;结果是它只是未格式化的代码,使一切都不清楚)。将编辑。
- @Shynthreir:看问题预编辑…
- 抱歉,我知道一定有原因。
1.7为十进制。在二进制中,它具有非有限表示。
因此,1.7和1.7f不同。
启发式证明:如果二进制表示是"有限的",那么当您将位向左移位(即乘以2)时,它最终将是一个整数。
但在十进制中,将1.7乘以2,然后再次:您将只获得非整数(十进制部分将在.4、.8、.6和.2之间循环)。因此,1.7不是2的幂和。
不能比较浮点变量是否相等。原因是小数部分用二进制表示,这意味着精度降低。