我需要找到最多和最少8个浮点值。我做了如下。但任何好的C书警告说,浮动比较会出错! 如何以准确的方式计算最大值和最小值。
main()
{
float mx,mx1,mx2,mx3,mx4,mn,mn1,mn2,mn3,mn4,tm1,tm2;
mx1 = mymax(2.1,2.01); //this returns 2.09999 instead of 2.1 because a is passed as 2.09999.
mx2 = mymax(-3.5,7.000001);
mx3 = mymax(7,5);
mx4 = mymax(7.0000011,0); //this returns incorrectly- 7.000001
tm1 = mymax(mx1,mx2);
tm2 = mymax(mx3,mx4);
mx = mymax(tm1,tm2);
mn1 = mymin(2.1,2.01);
mn2 = mymin(-3.5,7.000001);
mn3 = mymin(7,5);
mn4 = mymin(7.0000011,0);
tm1 = mymin(mx1,mx2);
tm2 = mymin(mx3,mx4);
mn = mymin(tm1,tm2);
printf("Max is %f, Min is %f \n",mx,mn);
getch();
}
float mymax(float a,float b)
{
if(a >= b)
{
return a;
}
else
{
return b;
}
}
float mymin(float a,float b)
{
if(a <= b)
{
return a;
}
else
{
return b;
}
}
如何对这些花车进行精确比较?这都是C代码。
谢谢。-AD。
答案 0 :(得分:2)
您正在对这些花车进行精确比较。问题(至少使用您的示例代码)是float
根本没有足够的精度数字来充分表示文字的值。 7.000001
和7.0000011
只是如此接近,以至于32位float
的尾数不能以不同方式表示它们。
但这个例子似乎是人为的。你想要解决的真正问题是什么?你实际上将使用什么价值观?或者这只是一次学术活动?
最佳解决方案取决于答案。如果您的实际值只需要比float
提供的更精确,请使用double
。如果需要精确表示十进制数字,请使用十进制类型库。如果您想要提高对浮点值如何工作的理解,请阅读The Floating-Point Guide。
答案 1 :(得分:0)
您可以对浮动进行精确比较。直接作为浮点数,或者通过使用相同的位表示将它们转换为int。
float a = 1.0f;
float b = 2.0f;
int &ia = *(int *)(&a);
int &ib = *(int *)(&b);
/* you can compare a and b, or ia and ib, the results will be the same,
whatever the values of the floats are.
Floats are ordered the correct way when its bits are considered as int
and thus can be compared (provided that float and int both are 32 bits).
*/
但你永远不会能够完全代表2.1作为浮动。
您的问题不是比较问题,而是表示值的问题。
答案 2 :(得分:0)
我声称这些比较实际上是准确的,因为没有改变价值。
问题是许多浮点文字无法用IEEE-754浮点数精确表示。所以例如2.1。
如果您需要基本10个指向数字的精确表示,您可以 - 例如 - 编写您自己的定点BCD算法。
关于同时找到最小值和最大值:
需要较少比较的方法是每个索引对(2 * i,2 * i + 1)首先找到最小值(n / 2比较)
然后找到最小值((n-1)/ 2比较)和最大值((n-1)/ 2比较)。
因此,当找到最小和最大分离时,我们得到(3 * n-2)/ 2比较而不是(2 * n-2)/ 2。
答案 3 :(得分:0)
<
和>
比较始终与浮点数或双精度数相符。只有==
比较有问题,因此建议您使用epsilon。
所以你的计算min,max的方法没有问题。请注意,如果您使用float,则应使用符号2.1f
而不是2.1
。只是一张便条。