我想知道是否有一种克服准确性问题的方法,这似乎是我机器内部浮点数的内部表示的结果:

为了清楚起见,问题总结为:

// str is "4.600";   atof( str ) is 4.5999999999999996  
double mw = atof( str )  

// The variables used in the columns calculation below are:   
//  
//                    mw = 4.5999999999999996  
//                    p = 0.2  
//                    g = 0.2  
//                    h = 1 (integer)  

int columns = (int) ( ( mw - ( h * 11 * p ) ) / ( ( h * 11 * p ) + g ) ) + 1;

在施放整数类型之前,列计算的结果为1.999999999999966;如此接近2.0的期望结果。

任何最欢迎的建议。

有帮助吗?

解决方案

一种非常简单有效的方法,将浮点数绕到整数:

int rounded = (int)(f + 0.5);

注意:这仅在 f 总是积极的。 (感谢J随机黑客)

其他提示

当您使用浮点时,算术严格平等几乎毫无意义。您通常想与一系列可接受的值进行比较。

请注意,某些值可以 不是 完全表示为浮点vlues。

每个计算机科学家对浮点算术都应了解什么比较浮点数.

没有准确的问题。

您得到的结果(1.99999999999996)与数学结果(2)的差异为1E-16。考虑到您的输入“ 4.600”,这是非常准确的。

当然,您确实有一个圆形问题。 C ++中的默认舍入是截断;您想要类似于KIP解决方案的东西。细节取决于您的确切领域,您期望 round(-x)== - round(x) ?

如果您还没有阅读, 这张纸 真的是正确的。请考虑阅读它,以了解有关现代计算机上浮点算术的基础知识的更多信息,一些陷阱以及解释为什么它们的行为方式。

如果准确性真的很重要,那么您应该考虑使用双精度浮点数,而不仅仅是浮点。虽然从您的问题来看,您似乎已经是。但是,您仍然有检查特定值的问题。您需要沿着(假设您对零检查值检查)的代码:

if (abs(value) < epsilon)
{
   // Do Stuff
}

其中“ epsilon”是一些小但非零值。

在计算机上,浮点数绝不精确。它们总是只是一个接近的近似值。 (1E-16接近。)

有时有隐藏的钻头您看不到。有时,代数的基本规则不再适用:a*b!= b*a。有时将寄存器与内存进行比较会显示出这些细微的差异。或使用数学协调员与运行时浮点库。 (我一直在做这个很长的时间。)

C99定义:(看一下 Math.H)

double round(double x);
float roundf(float x);
long double roundl(long double x);

.

或者您可以自己滚动:

template<class TYPE> inline int ROUND(const TYPE & x)
{ return int( (x > 0) ? (x + 0.5) : (x - 0.5) ); }

对于浮点等效性,请尝试:

template<class TYPE> inline TYPE ABS(const TYPE & t)
{ return t>=0 ? t : - t; }

template<class TYPE> inline bool FLOAT_EQUIVALENT(
    const TYPE & x, const TYPE & y, const TYPE & epsilon )
{ return ABS(x-y) < epsilon; }

使用小数: decnumber ++

你可以阅读此 找到您要寻找的东西。

您可以获得结果的绝对值 这里:

x = 0.2;  
y = 0.3;  
equal = (Math.abs(x - y) < 0.000001)  
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top