如何在C中进行舍入?
我有一个代码示例:如何在C中进行舍入?,c,floating-point,rounding,C,Floating Point,Rounding,我有一个代码示例: float f = 3.55f; printf("%.1f\n", f); 结果是3.5,而不是期望的3.6 float delta = 1e-7; float f = 3.55f; printf("%.1f\n", f+delta); 现在的结果是3.6,但当f为0.04999f时 printf("%.1f\n", f+delta); 结果是0.1,而不是0.0 我需要一个能将3.55转换为3.6、0.049999转换为0.0的函数,有人给我提供线索吗?与许多浮点问题
float f = 3.55f;
printf("%.1f\n", f);
结果是3.5,而不是期望的3.6
float delta = 1e-7;
float f = 3.55f;
printf("%.1f\n", f+delta);
现在的结果是3.6,但当f为0.04999f时
printf("%.1f\n", f+delta);
结果是0.1,而不是0.0
我需要一个能将3.55转换为3.6、0.049999转换为0.0的函数,有人给我提供线索吗?与许多浮点问题一样,问题是您的值: 另见
因此,除非您使用
ceil()
,否则此值永远不会向上取整。此代码在这里起作用。我对代码进行了注释,以便您能够理解它
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
float delta = 1e-7;
float f = 3.55f;
// Here we minus f (3.55) from the integer of f (3) so 3.55 - 3 = 0.55
// Then we check whether the value is bigger than 0.5
if( (f-(int)f) >= 0.5 ) {
// If it is, then plus 0.01 to the answer. Thus making it 3.65
f = f + 0.01;
} else {
// If its not, minus 0.01 from the answer.
// Assuming f is 3.44 this will make f 3.43
f = f - 0.01;
}
// Since you its to the first decimal place, the code above will output
// your desired result which is 3.6.
printf("%.1f\n", f+delta);
return 0;
}
#包括
#包括
int main(int argc,char const*argv[]
{
浮动增量=1e-7;
浮球f=3.55f;
//这里我们从f(3)的整数中减去f(3.55),所以3.55-3=0.55
//然后我们检查该值是否大于0.5
如果((f-(int)f)>=0.5){
//如果是的话,那么答案加上0.01,因此是3.65
f=f+0.01;
}否则{
//如果不是,从答案中减去0.01。
//假设f为3.44,则f为3.43
f=f-0.01;
}
//由于将其保留到第一个小数位,因此将输出上面的代码
//你想要的结果是3.6。
printf(“%.1f\n”,f+delta);
返回0;
}
对的修改产生所需的输出:
float custom_round(float num, int prec)
{
float trunc = round(num * pow(10, prec+7));
trunc = round(trunc/pow(10, 7));
return trunc / pow(10, prec);
}
7
额外精度来自delta
值。我不认为它是普遍适用的,但对于两个数字3.55f
和0.04999f
,它指出了一个位置,第一个数字将向上取整,而第二个数字将向下取整。我希望这对您有所帮助。这里有一个完整的取整程序,但您只能使用该函数
#include <stdio.h>
#include <math.h>
#include <string.h>
//function prototypes
float roundon(float n,int to);
void main(){
//vars
float num;
int roundto;
puts("Enter the decimal to be rounded");
scanf("%f",&num);
puts("Enter the number of decimal places to be rounded");
scanf("%d",&roundto);
float rounded= roundon(num,roundto);
printf("The rounded value is %f\n",rounded);
}
//functions
float roundon(float n, int to){
//vars
float rounded;
int checker=(int) (n*pow(10,(to+1)))%10;
int dec= (int) (n*pow(10,to));
if(checker>=5){
dec++;
}
rounded= (float) dec/(pow(10,to));
return (rounded);
}
#包括
#包括
#包括
//功能原型
浮动环行交叉口(浮动n,整数至);
void main(){
//瓦尔斯
浮点数;
国际圆桌会议;
puts(“输入要四舍五入的小数点”);
scanf(“%f”、&num);
puts(“输入要四舍五入的小数位数”);
scanf(“%d”、&roundto);
浮点四舍五入=圆形(num,roundto);
printf(“四舍五入值为%f\n”,四舍五入);
}
//功能
浮动环行交叉口(浮动n,整数到){
//瓦尔斯
浮圆;
整数校验器=(整数)(n*pow(10,(to+1)))%10;
整数dec=(整数)(n*pow(10,to));
如果(检查器>=5){
dec++;
}
四舍五入=(浮动)十二月/(功率(10到));
返回(四舍五入);
}
其他人指出,示例中的十进制值没有精确的二进制等价物
然后是三角洲:
对于16Q范围内的单精度数字x:。。。将3.55转换为3.6,0.049999转换为0.0…?
答:使用@Kninnug答案,但保留小数点后1位
f = round(f * 10) / 10.0;
它将为您提供3.5
,因为数字f
最初不是3.55。确实,您使用文本“3.55”初始化了f
,但是C
并且您的计算机无法准确表示该数字您的系统上没有(浮动)3.55。相反,f
的值约为3.54999952…
,因为它是最接近的选择
如果仍要将f
四舍五入到3.6而不是3.5,则需要将f
稍微向上推一点。当它是3.54999952…
时,它的值>=3.55;当f
是0.049990016…
(0.0499999也不完全可表示)时,相同的轻推使它保持f
<0.5
我们可以增加f
的最小值是nextafterf(f,g)
g
是您希望向其移动的值
3.549999952... --> 3.550000190...
0.04999990016... --> 0.04999990389...
printf("%.1f\n", nextafterf(f, 2*f));
// prints 3.6 when f is 3.549999952...
// prints 0.0 when f is 0.04999990389...
建议您查看@Oli Charlesworth答案中的参考资料 在第二个示例中尝试此函数,您确定仅仅声明另一个变量就会改变
printf()
的行为吗?尝试添加所需精度的一半,例如f+0.05
,然后使用%.1f
(或0.005和%.2f
等)打印。顺便说一句,.1f
打印.1f
,缺少%
。如果在编译代码时启用警告,编译器会警告您缺少“%”。在带有gcc的Linux下,它打印了警告:格式[-Wformat extra args]的参数太多
,这一行显然有错误。输入要舍入的小数点523.567输入要舍入的小数点位数2舍入值为523.570007(这是我在上面程序中的输出,但我不确定后面的00007是从哪里来的,但你可以解决这个问题。无论如何,我使用的是Linux,你可能使用了其他操作系统)
3.549999952... --> 3.550000190...
0.04999990016... --> 0.04999990389...
printf("%.1f\n", nextafterf(f, 2*f));
// prints 3.6 when f is 3.549999952...
// prints 0.0 when f is 0.04999990389...