舍入C ++中的double值,如MS Excel

我在网上search过,但找不到解决问题的办法。 我只是想要一个函数,像MS Excel一样舍入double值。 这是我的代码:

#include <iostream> #include "math.h" using namespace std; double Round(double value, int precision) { return floor(((value * pow(10.0, precision)) + 0.5)) / pow(10.0, precision); } int main(int argc, char *argv[]) { /* The way MS Excel does it: 1.27815 1.27840 -> 1.27828 1.27813 1.27840 -> 1.27827 1.27819 1.27843 -> 1.27831 1.27999 1.28024 -> 1.28012 1.27839 1.27866 -> 1.27853 */ cout << Round((1.27815 + 1.27840)/2, 5) << "\n"; // * cout << Round((1.27813 + 1.27840)/2, 5) << "\n"; cout << Round((1.27819 + 1.27843)/2, 5) << "\n"; cout << Round((1.27999 + 1.28024)/2, 5) << "\n"; // * cout << Round((1.27839 + 1.27866)/2, 5) << "\n"; // * if(Round((1.27815 + 1.27840)/2, 5) == 1.27828) { cout << "Hurray...\n"; } system("PAUSE"); return EXIT_SUCCESS; } 

我在这里find了函数在stackoverflow,答案说,它的工作原理像内置的Excel四舍五入例程,但它不。 你能告诉我我错过了什么吗?

从某种意义上说,你所要求的是不可能的:

大多数通用平台上的浮点值不具有“小数位数”的概念。 像2.3或8.71这样的数字根本无法精确表示。 因此,要求任何函数返回给定数量的非零小数位的浮点值是没有意义的 – 这样的数字根本就不存在

浮点types唯一可以做的就是计算最接近的可表示的近似值,然后用所需的精度打印结果,这会给出你想要的数字的文本forms。 为了计算表示,你可以这样做:

 double round(double x, int n) { int e; double d; std::frexp(x, &e); if (e >= 0) return x; // number is an integer, nothing to do double const f = std::pow(10.0, n); std::modf(x * f, &d); // d == integral part of 10^n * x return d / f; } 

(你也可以使用modf而不是frexp来确定x是否是一个整数,你还应该检查n是否定的,否则定义负的“精度”的语义)。

除了使用浮点types,您可以执行定点算术。 也就是说,你把所有东西都存为整数 ,但是把它们当作1/1000的单位。 那么你可以打印这样一个数字如下:

  std::cout << n / 1000 << "." << n % 1000; 

加法运作如预期,但你必须编写自己的乘法函数。

要比较double值,必须指定一个比较范围,其中结果可以被认为是“安全的”。 你可以使用一个macros。

以下是您可以使用的一个示例:

 #define COMPARE( A, B, PRECISION ) ( ( A >= B - PRECISION ) && ( A <= B + PRECISION ) ) int main() { double a = 12.34567; bool equal = COMPARE( a, 12.34567F, 0.0002 ); equal = COMPARE( a, 15.34567F, 0.0002 ); return 0; } 

恐怕答案是Round不能施展魔法。
由于1.27828并不能完全代表双倍数,所以你不能把一些双重数字与1.27828做比较,并希望它能匹配。

你需要做的math没有小数部分,以获得这个数字…所以这样的事情。

 double dPow = pow(10.0, 5.0); double a = 1.27815; double b = 1.27840; double a2 = 1.27815 * dPow; double b2 = 1.27840 * dPow; double c = (a2 + b2) / 2 + 0.5; 

使用你的function…

 double c = (Round(a) + Round(b)) / 2 + 0.5; 

谢谢大家的答案! 在考虑了可能的解决scheme之后,我在代码中将原来的Round()函数更改为0.6,而不是0.5。

值“127827.5”(我明白,这不是一个确切的表示forms!)变成“127828.1”,最后通过floor()并将其划分为“1.27828”(或更像1.2782800..001)。 使用Renan Greinertbuild议的COMPARE,select正确的精度,我可以安全地比较现在的值。

这是最终版本:

 #include <iostream> #include "math.h" #define COMPARE(A, B, PRECISION) ((A >= B-PRECISION) && (A <= B+PRECISION)) using namespace std; double Round(double value, int precision) { return floor(value * pow(10.0, precision) + 0.6) / pow(10.0, precision); } int main(int argc, char *argv[]) { /* The way MS Excel does it: 1.27815 1.27840 // 1.27828 1.27813 1.27840 -> 1.27827 1.27819 1.27843 -> 1.27831 1.27999 1.28024 -> 1.28012 1.27839 1.27866 -> 1.27853 */ cout << Round((1.27815 + 1.27840)/2, 5) << "\n"; cout << Round((1.27813 + 1.27840)/2, 5) << "\n"; cout << Round((1.27819 + 1.27843)/2, 5) << "\n"; cout << Round((1.27999 + 1.28024)/2, 5) << "\n"; cout << Round((1.27839 + 1.27866)/2, 5) << "\n"; //Comparing the rounded value against a fixed one if(COMPARE(Round((1.27815 + 1.27840)/2, 5), 1.27828, 0.000001)) { cout << "Hurray!\n"; } //Comparing two rounded values if(COMPARE(Round((1.27815 + 1.27840)/2, 5), Round((1.27814 + 1.27841)/2, 5), 0.000001)) { cout << "Hurray!\n"; } system("PAUSE"); return EXIT_SUCCESS; } 

我已经通过四舍五入的数值进行了testing,并且比较了Excel给出的结果。 他们都是一样的。