是否有一个函数可以在 C 中舍入一个浮点数,还是我需要自己编写?
浮点转换 = 45. 59 2346543;
我想将实际值四舍五入到小数点后一位, conver = 45. 6。
是否有一个函数可以在 C 中舍入一个浮点数,还是我需要自己编写?
浮点转换 = 45. 59 2346543;
我想将实际值四舍五入到小数点后一位, conver = 45. 6。
当然,您可以使用roundf()。如果你想四舍五入到小数点后,你可以这样做:roundf(10 * x) / 10
正如 Rob 所提到的,您可能只想将浮点数打印到小数点后 1 位。在这种情况下,您可以执行以下操作:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float conver = 45.592346543;
printf("conver is %0.1f\n",conver);
return 0;
}
如果你想实际四舍五入存储的值,那就有点复杂了。一方面,您的一位小数位表示很少有精确的浮点模拟。如果你只是想尽可能靠近,这样的事情可能会奏效:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float conver = 45.592346543;
printf("conver is %0.1f\n",conver);
conver = conver*10.0f;
conver = (conver > (floor(conver)+0.5f)) ? ceil(conver) : floor(conver);
conver = conver/10.0f;
//If you're using C99 or better, rather than ANSI C/C89/C90, the following will also work.
//conver = roundf(conver*10.0f)/10.0f;
printf("conver is now %f\n",conver);
return 0;
}
我怀疑第二个示例是您要查找的内容,但为了完整起见,我将其包含在内。如果您确实需要在内部以这种方式表示您的数字,而不仅仅是在输出上,请考虑使用定点表示。
#include <math.h>
double round(double x);
float roundf(float x);
不要忘记与 -lm 链接。另请参见 ceil()、floor() 和 trunc()。
只是为了概括 Rob 的回答,如果您不在输出上执行此操作,您仍然可以使用与sprintf()
.
不过,我认为还有另一种方法可以做到这一点。你可以尝试ceil()
上下floor()
四舍五入。一个很好的技巧是添加 0.5,因此任何超过 0.5 的内容都会向上取整,但低于 0.5 的任何内容都会向下取整。ceil()
并且floor()
只在double
s 上工作。
编辑:另外,对于浮点数,您可以使用truncf()
截断浮点数。相同的 +0.5 技巧应该可以进行精确的舍入。
要打印一个四舍五入的值,@Matt J很好地回答了这个问题。
float x = 45.592346543;
printf("%0.1f\n", x); // 45.6
由于大多数浮点 (FP) 是基于二进制的,因此当数学上正确的答案是 时,不可能精确四舍五入到小数点x.1, x.2, ...
后一位。
将 FP 编号转换为最接近 0.1
的数字是另一回事。
溢出:首先按 10(或 100、1000 等)缩放的方法可能会溢出 large x
.
float round_tenth1(float x) {
x = x * 10.0f;
...
}
双舍入floorf(x*10.0f + 0.5f)/10.0
:当中间和向上舍入x*10.0f + 0.5f
到一个新整数时,添加 0.5f 然后使用返回错误的结果。
// Fails to round 838860.4375 correctly, comes up with 838860.5
// 0.4499999880790710449 fails as it rounds to 0.5
float round_tenth2(float x) {
if (x < 0.0) {
return ceilf(x*10.0f + 0.5f)/10.0f;
}
return floorf(x*10.0f + 0.5f)/10.0f;
}
投到远大于时int
有明显的问题。float x
INT_MAX
使用roundf()
和家庭,可用<math.h>
是最好的方法。
float round_tenthA(float x) {
double x10 = 10.0 * x;
return (float) (round(x10)/10.0);
}
为避免使用double
,只需测试数字是否需要四舍五入。
float round_tenthB(float x) {
const float limit = 1.0/FLT_EPSILON;
if (fabsf(x) < limit) {
return roundf(x*10.0f)/10.0f;
}
return x;
}
还有一个round()
函数,也fround()
可以四舍五入到最接近的整数,表示为双精度数。但这不是你想要的。
我有同样的问题并写了这个:
#include <math.h>
double db_round(double value, int nsig)
/* ===============
**
** Rounds double <value> to <nsig> significant figures. Always rounds
** away from zero, so -2.6 to 1 sig fig will become -3.0.
**
** <nsig> should be in the range 1 - 15
*/
{
double a, b;
long long i;
int neg = 0;
if(!value) return value;
if(value < 0.0)
{
value = -value;
neg = 1;
}
i = nsig - log10(value);
if(i) a = pow(10.0, (double)i);
else a = 1.0;
b = value * a;
i = b + 0.5;
value = i / a;
return neg ? -value : value;
}
你可以使用#define round(a) (int) (a+0.5) 作为宏,所以当你写 round(1.6) 时它返回 2,而当你写 round(1.3) 时它返回 1。