C++ Visual Studio Express 2012 中的舍入错误
Rounding error in C++ Visual Studio Express 2012
我在尝试用 C++ 编写自己的舍入函数时遇到了一个非常奇怪的功能。
以下两个函数的输出都是 0.000。
double round ( double x, int y)
{
double value = 0;
value = floor(x*pow(10, y) + x>=0?0.5:-0.5)/pow(10, y);
return value;
}
double round3(double x)
{
double value = 0;
value = floor(x * 1000 + x>=0?0.5:-0.5) / 1000;
return value;
}
但是此函数会产生正确的输出,四舍五入到小数点后 3 位。
double round(double x)
{
double value = 0;
if (x >= 0){
value = floor( x*1000 + 0.5 )/1000;
}
else{
value = floor( x*1000 - 0.5 )/1000;
}
return value;
}
谁能告诉我为什么会这样?
三元运算符?:
的优先级比较低,this
x * 1000 + x>=0?0.5:-0.5
相当于:
(x * 1000 + x>=0)?0.5 :-0.5
结果为 0.5
或 -0.5
。
前两个有 operator precendence 个错误,例如(x * 1000 + x>=0?0.5:-0.5) / 1000
被计算为 (((x * 1000 + x) >= 0) ? 0.5 : -0.5) / 1000
,因此当 x
为正时为 0.0005,当 x
为负时为 -0.0005。
还要记住,"rounding" 双打是一件棘手的事情...第 15 位或第 16 位通常会有错误,是否因为 "mathematically perfect" 运算结果已执行不能在 double
变量中准确表示,或者由于中间值或数学函数(如 pow
中的近似值,因此您可能会发现您认为是 "n.5" 的值有时向上舍入,有时向下舍入。如果对此感到困惑,也许阅读 What Every Computer Scientist Should Know About Floating-Point Arithmetic.
我在尝试用 C++ 编写自己的舍入函数时遇到了一个非常奇怪的功能。
以下两个函数的输出都是 0.000。
double round ( double x, int y)
{
double value = 0;
value = floor(x*pow(10, y) + x>=0?0.5:-0.5)/pow(10, y);
return value;
}
double round3(double x)
{
double value = 0;
value = floor(x * 1000 + x>=0?0.5:-0.5) / 1000;
return value;
}
但是此函数会产生正确的输出,四舍五入到小数点后 3 位。
double round(double x)
{
double value = 0;
if (x >= 0){
value = floor( x*1000 + 0.5 )/1000;
}
else{
value = floor( x*1000 - 0.5 )/1000;
}
return value;
}
谁能告诉我为什么会这样?
三元运算符?:
的优先级比较低,this
x * 1000 + x>=0?0.5:-0.5
相当于:
(x * 1000 + x>=0)?0.5 :-0.5
结果为 0.5
或 -0.5
。
前两个有 operator precendence 个错误,例如(x * 1000 + x>=0?0.5:-0.5) / 1000
被计算为 (((x * 1000 + x) >= 0) ? 0.5 : -0.5) / 1000
,因此当 x
为正时为 0.0005,当 x
为负时为 -0.0005。
还要记住,"rounding" 双打是一件棘手的事情...第 15 位或第 16 位通常会有错误,是否因为 "mathematically perfect" 运算结果已执行不能在 double
变量中准确表示,或者由于中间值或数学函数(如 pow
中的近似值,因此您可能会发现您认为是 "n.5" 的值有时向上舍入,有时向下舍入。如果对此感到困惑,也许阅读 What Every Computer Scientist Should Know About Floating-Point Arithmetic.