C++ 用数学方法将浮点四舍五入到小数点后N位

C++ 用数学方法将浮点四舍五入到小数点后N位,c++,c,codeblocks,C++,C,Codeblocks,我想把一个浮点数/双精度数四舍五入到小数点后n位。但不是在印刷业,而是在一般情况下 e、 g:用户的输入是:2.3891 3,所以输出应该是2.389 或者,如果用户的输入为5.98441 4,则输出应为:5.9844 #include <stdio.h> #include <math.h> int main () { float num; int decimals; scanf("%f%d", &num, &decimals); //5.2381

我想把一个浮点数/双精度数四舍五入到小数点后n位。但不是在印刷业,而是在一般情况下
e、 g:用户的输入是:2.3891 3,所以输出应该是2.389
或者,如果用户的输入为5.98441 4,则输出应为:5.9844

#include <stdio.h>
#include <math.h>

int main () {

float num;
int decimals;

scanf("%f%d", &num, &decimals); //5.2381 2

int res = num; // res = 5

int power = 1;
int i = 0;
for(i = 0; i < decimals; i++)
    power*=10; // 1 * 10 * 10

int num3 = num * power; // num3 = 523
int num2 = num3 % power;//

float a = num2*1.0 / power*1.0;
// float a = 23*1.0/13.0;
printf("%f %d\n", a, power);

a = res + a;

printf("%f", a);

return 0;
}
#包括
#包括
int main(){
浮点数;
整数小数;
scanf(“%f%d”,&num,&decimals);//5.2381 2
int res=num;//res=5
整数幂=1;
int i=0;
对于(i=0;i<小数;i++)
功率*=10;//1*10*10
int num3=num*power;//num3=523
int num2=num3%功率//
浮子a=num2*1.0/功率*1.0;
//浮点数a=23*1.0/13.0;
printf(“%f%d\n”,a,电源);
a=res+a;
printf(“%f”,a);
返回0;
}

作为这里的输出,我得到:239000。我不想使用这些零,也不想使用固定%.2f。我遗漏了什么?

一般来说,这项任务是不可能的,因为IEEE 754转换是浮点或双精度二进制浮点的表示。因此,上面一行
scanf(“%f%d”,&num,&decimals)//5.2381 2
将十进制(以10为基数)数转换为二进制浮点数,这种转换通常不是EXEXT,因为您只有有限的位数。 您可以减少位(二进制)的数量,但这不是在十进制系统中定义的。
打印浮点(双精度)数字时,由于将二进制浮点计算转换为十进制浮点计算,会出现第二次不精确。

一般来说,这是不可能的。C和C++中的浮点最终根据基数、尾数、符号和指数来指定。 十进制浮点是以10为基数的。在现代硬件的实践中,这是极其罕见的。一些早期的计算硬件(如1946年创建的ENIAC)支持十进制浮点。然而,这种表示在现代硬件中非常罕见

现代硬件上最常见的浮点表示法使用
2
(即二进制)作为基数。二进制浮点不能表示所有小数。尝试使用
2
的负幂和来表示十进制值
0.1
(如
1/2
1/4
1/8
等)。您会发现
0.1
的表示法包含一个十进制的无穷级数。原因类似于分数
1/3
不能以有限的小数位数表示(即
0.33333….
其中数字
3
永远重复)


无理值(如
sqrt(2.0)
pi
,以及其他)也不能用有限位数的任何基数精确表示。因此,不可能设计一种固定大小和有限大小的浮点类型来精确保存这些值。

这里有两件事要做:1)计算一个数字的舍入值,2)打印该数字

计算舍入值 你做得很对。请注意,当将
浮点
隐式转换为
int
时,C执行的是截断,而不是舍入,因此:

float f = 1.9;
int i = f;
i
设置为
1
,而不是
2
。在您的例子中,如果输入为“1.229 2”,则计算的值为1.22,而不是1.23。这可能是你想要的,但可能不是。如果要舍入而不是接近零,则可能需要更改此选项:

int num3 = num * power;
致:

打印舍入值 一旦计算了值,就可以打印它。如果只想打印四舍五入到的小数位数,可以使用
printf()
的精度字段,如下所示:

printf("%.*f\n", decimals, a);

你所要求的是不可能的。浮点数没有小数点。@melpomene“二进制浮点数”准确地说是“二进制浮点数”,因为它们确实存在。但是你是对的。你可以使用
printf(“%g”,a)将。始终使用
double
(忘记
float
存在)
double roundn(double x,int n){double b=pow(10,n);int c=(x+0.5)*b;/*心灵溢出*/返回c/b;}
@UlrichEckhardt:唯一比
double
更好的是空间需求
double
更精确,
double
通常更快,
double
避免了到处自动转换为
double
。每个浮点变量增加4个字节不会对可执行文件产生影响(当然,除非您需要巨大的数组)。在
float中x=42,y;y=x*2有2种自动转换:首先,在乘法之前,x转换为double;在现代硬件中,十进制并不“非常”罕见。它不存在于普通的个人电脑中。例如,IBM为商业/工业用途制造十进制硬件。事实上,如果只需要对输出表示进行四舍五入,则使用您正确支持的打印技术;
printf()
函数将正确舍入。
printf("%.*f\n", decimals, a);