Dal*_*und 389
如果您只想将数字四舍五入以进行输出,那么"%.2f"格式字符串确实是正确的答案.但是,如果您确实要将浮点值舍入以进行进一步计算,则类似以下内容的工作方式:
#include <math.h>
float val = 37.777779;
float rounded_down = floorf(val * 100) / 100; /* Result: 37.77 */
float nearest = roundf(val * 100) / 100; /* Result: 37.78 */
float rounded_up = ceilf(val * 100) / 100; /* Result: 37.78 */
Run Code Online (Sandbox Code Playgroud)
请注意,您可能要选择三种不同的舍入规则:向下舍入(即,在两位小数后截断),四舍五入到最近,舍入.通常,你想要舍入到最近.
正如其他几个人所指出的那样,由于浮点表示的怪癖,这些舍入值可能不是"明显的"十进制值,但它们将非常接近.
关于四舍五入的更多信息(特别是关于舍入到最近的打破平局规则),请参阅关于舍入的维基百科文章.
And*_*son 77
printf("%.2f", 37.777779);
Run Code Online (Sandbox Code Playgroud)
Joh*_*ter 42
假设你正在谈论打印的价值,那么Andrew Coleson和AraK的回答是正确的:
printf("%.2f", 37.777779);
Run Code Online (Sandbox Code Playgroud)
但请注意,如果你的目标是将数字四舍五入到37.78用于内部使用(例如与另一个值进行比较),那么这不是一个好主意,因为浮点数的工作方式:你通常不会想要对浮点进行相等比较,而是使用目标值+/- sigma值.或者将数字编码为具有已知精度的字符串,并进行比较.
请参阅Greg Hewgill对相关问题的回答中的链接,该问题还包括为什么不应使用浮点进行财务计算.
Dan*_*iil 22
这个怎么样:
float value = 37.777779;
float rounded = ((int)(value * 100 + .5) / 100.0);
Run Code Online (Sandbox Code Playgroud)
Ara*_*raK 20
printf("%.2f", 37.777779);
Run Code Online (Sandbox Code Playgroud)
如果要写入C-string:
char number[24]; // dummy size, you should take care of the size!
sprintf(number, "%.2f", 37.777779);
Run Code Online (Sandbox Code Playgroud)
And*_*ton 11
没有办法将a 舍入float到另一个,float因为舍入float可能无法表示(浮点数的限制).例如,假设您将37.777779舍入到37.78,但最接近的可表示数字是37.781.
但是,您可以float使用格式字符串函数"舍入"a .
此外,如果您使用的是C++,则只需创建如下函数:
string prd(const double x, const int decDigits) {
stringstream ss;
ss << fixed;
ss.precision(decDigits); // set # places after decimal
ss << x;
return ss.str();
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用以下代码输出任何myDouble带n小数点后位置的双精度数:
std::cout << prd(myDouble,n);
Run Code Online (Sandbox Code Playgroud)
你仍然可以使用:
float ceilf(float x); // don't forget #include <math.h> and link with -lm.
Run Code Online (Sandbox Code Playgroud)
例:
float valueToRound = 37.777779;
float roundedValue = ceilf(valueToRound * 100) / 100;
Run Code Online (Sandbox Code Playgroud)
在C++中(或在C中使用C风格的强制转换),您可以创建函数:
/* Function to control # of decimal places to be output for x */
double showDecimals(const double& x, const int& numDecimals) {
int y=x;
double z=x-y;
double m=pow(10,numDecimals);
double q=z*m;
double r=round(q);
return static_cast<double>(y)+(1.0/m)*r;
}
Run Code Online (Sandbox Code Playgroud)
然后std::cout << showDecimals(37.777779,2);会产生:37.78.
显然你并不需要在该函数中创建所有5个变量,但我将它们留在那里以便您可以看到逻辑.可能有更简单的解决方案,但这对我很有用 - 特别是因为它允许我根据需要调整小数位后的位数.
printf为此,请始终使用功能族。即使您希望以浮点数形式获取值,也最好使用snprintf将取整后的值作为字符串获取,然后使用以下方法将其解析回atof:
#include <math.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
double dround(double val, int dp) {
int charsNeeded = 1 + snprintf(NULL, 0, "%.*f", dp, val);
char *buffer = malloc(charsNeeded);
snprintf(buffer, charsNeeded, "%.*f", dp, val);
double result = atof(buffer);
free(buffer);
return result;
}
Run Code Online (Sandbox Code Playgroud)
我之所以这样说,是因为目前投票最多的答案以及此处的其他几个答案所示的方法-乘以100,四舍五入为最接近的整数,然后再除以100,则该方法存在两种缺陷:
为了说明第一种错误-舍入方向有时是错误的-尝试运行以下程序:
#include <math.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
double dround(double val, int dp) {
int charsNeeded = 1 + snprintf(NULL, 0, "%.*f", dp, val);
char *buffer = malloc(charsNeeded);
snprintf(buffer, charsNeeded, "%.*f", dp, val);
double result = atof(buffer);
free(buffer);
return result;
}
Run Code Online (Sandbox Code Playgroud)
您将看到以下输出:
int main(void) {
// This number is EXACTLY representable as a double
double x = 0.01499999999999999944488848768742172978818416595458984375;
printf("x: %.50f\n", x);
double res1 = dround(x, 2);
double res2 = round(100 * x) / 100;
printf("Rounded with snprintf: %.50f\n", res1);
printf("Rounded with round, then divided: %.50f\n", res2);
}
Run Code Online (Sandbox Code Playgroud)
请注意,我们开始时的值小于0.015,因此将其舍入到小数点后两位时的数学正确答案为0.01。当然,不能精确地将 0.01 表示为双精度数,但是我们希望我们的结果是最接近0.01的双精度数。使用snprintf给出结果,但是使用round(100 * x) / 1000.02,这是错误的。为什么?因为100 * x给出的结果恰好是1.5。因此,乘以100会更改正确的方向以四舍五入。
为了说明第二类型的错误-结果有时是错误的,由于* 100并/ 100没有真正被对方的逆-我们可以做一个类似的工作具有非常大的数字:
x: 0.01499999999999999944488848768742172978818416595459
Rounded with snprintf: 0.01000000000000000020816681711721685132943093776703
Rounded with round, then divided: 0.02000000000000000041633363423443370265886187553406
Run Code Online (Sandbox Code Playgroud)
现在,我们的数字甚至不占分数。它是一个整数值,仅与type存储在一起double。因此,四舍五入后的结果应该与开始时的数字相同,对吗?
如果您运行上面的程序,您将看到:
x: 8631192423766613.0
Rounded with snprintf: 8631192423766613.0
Rounded with round, then divided: 8631192423766612.0
Run Code Online (Sandbox Code Playgroud)
哎呀。我们的snprintf方法再次返回正确的结果,但是“乘-乘-乘-乘-乘-除”方法失败。这是因为数学上正确的值8631192423766613.0 * 100,863119242376661300.0是不是作为一个双精确表示; 最接近的值是863119242376661248.0。当您将其除以100时,得到8631192423766612.0的数字与开始时的数字不同。
希望这是一个充分的演示,证明roundf舍入到小数点后一位的位数是无效的,您应该snprintf改为使用。如果这对您来说真是骇人听闻的破解,那么也许您会被CPython的基本功所知。