C 中是否有对浮点数进行四舍五入的函数,还是我需要编写自己的函数?
浮点转换器 = 45.592346543;
我想将实际值四舍五入到小数点后一位,conver = 45.6.
正如 Rob 提到的,您可能只想打印浮点到小数点后一位。 在这种情况下,您可以执行以下操作:
#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;
}
我怀疑第二个示例是您正在寻找的,但为了完整性我将其包含在内。 如果您确实需要在内部以这种方式表示数字,而不仅仅是在输出上,请考虑使用定点表示。
当然,你可以使用roundf()。如果您想四舍五入到一位小数,那么您可以执行以下操作:
roundf(10 * x) / 10
#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
。
编辑:此外,对于浮点数,您可以使用
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 等)的方法可能会溢出较大的 x
。
float round_tenth1(float x) {
x = x * 10.0f;
...
}
双重舍入:当中间和floorf(x*10.0f + 0.5f)/10.0
向上舍入为新整数时,添加 0.5f 然后使用
x*10.0f + 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.0f/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;
}