格式化与四舍五入

本文将讨论在格式化输出浮点数时的四舍五入问题,为了便与讨论,将问题分为原始数据是浮点数,以及通过计算得到的浮点数两种情况。

本次测试使用的编译器为 Visual C++ 2015

前置知识

浮点数有两类:

  • float,单精度浮点型,有效位数为7位,格式化参数为 %f
  • double,双精度浮点型,有效位数为16位,格式化参数为 %lf

指定小数位方法的格式化语法:printf("%.*f", nDecimal, fValue)

原始数据是浮点数

一般采用 printf("%M.Nf", dValue)的语法进行格式化。M表示输出字符的最小宽度,N表示输出小数位数,当N为0时,表示不输出小数和小数点。当小数位不够N位,对于的位数补0。

以下是例子:

void test_format_float()
{
	double dTestZero = 1.2;
	printf("0.1 %.0f\n", dTestZero);
	dTestZero = 1.3;
	printf("0.2 %.0f\n", dTestZero);
	dTestZero = 1.4;
	printf("0.3 %.0f\n", dTestZero);
	dTestZero = 1.5;
	printf("0.4 %.0f\n", dTestZero);
	dTestZero = 1.6;
	printf("0.5 %.0f\n", dTestZero);

	double dTest = 1.2345678;
	printf("1.1 %4.0f\n", dTest);
	printf("1.2 %4.1f\n", dTest);
	printf("1.3 %4.2f\n", dTest);
	printf("1.4 %4.3f\n", dTest);
	printf("1.5 %4.4f\n", dTest);
	printf("1.6 %4.5f\n", dTest);
	printf("1.7 %4.6f\n", dTest);

	double dTest2 = 8.7654321;
	printf("2.1 %4.0f\n", dTest2);
	printf("2.2 %4.1f\n", dTest2);
	printf("2.3 %4.2f\n", dTest2);
	printf("2.4 %4.3f\n", dTest2);
	printf("2.5 %4.4f\n", dTest2);
	printf("2.6 %4.5f\n", dTest2);
	printf("2.7 %4.6f\n", dTest2);
}

输出结果如下:

输出小数格式化问题截图.jpg

小结:当按%M.Nf格式化输出浮点数,输出是满足四舍五入的规则。

原始数据是计算出来的浮点数

根据计算依赖的数据类型,可分为以下三种:

  • 浮点数和浮点数
  • 浮点数和整数
  • 整数和整数

浮点和浮点

这种情况和原始数据是浮点数是一样规则,此处不再赘述。

浮点数和整数

根据计算规则,此时会将整数提升为浮点数,然后进行计算,情况原始数据是浮点数

整数和整数

整数运算是没有四舍五入,当计算结果有小数时,会舍弃掉全部小数,这种规则,在某些情况下不是我们期望的。因此,需要一种方法,得到此场景下的小数显示。

梳理现有的,有两种方案:

  • 加上特定数值,并以%d输出。
    这种方法是给计算结果加上0.5,对计算结果的1位小数进行四舍五入。
	double dCount = 2087;
	int nUnit = 100;
	// 不保留小数,对整形结果进行四舍五入。
	printf("%d\n", (int)(dCount/nUnit + 0.5));	
    

这种做法的缺点是,只适合四舍五入1位小数,不适合其他场合,而且这个0.5在这里是个魔幻数字,可读性不好。

  • 将计算结果强制转换为浮动类型,再进行计算,例如:
	int a = 123456;
	int b = 100000;
	printf("5.0 %1.1f\n", a / b);
	printf("5.1 %1.1f\n", (double)a / b);
	printf("5.2 %1.2f\n", (double)a / b);
	printf("5.3 %1.3f\n", (double)a / b);
	printf("5.4 %1.4f\n", (double)a / b);
	printf("5.5 %1.5f\n", (double)a / b);
	printf("5.6 %1.6f\n", (double)a / b);

这种方案,适合各种不同小数位数的四舍五入场景,无魔幻数字,值得推荐。

小结

对浮点数的格式化输出,可采用 %M.Nf的格式,输出是按照四舍五入的规则。
当需要显示两个整形值的精确除法结果时,建议将其中一个变量强制转换为double类型再进行计算,简单直接。

参考文章:

printf输出时什么情况下四舍五入?

posted @ 2021-06-16 10:32  浩天之家  阅读(595)  评论(0编辑  收藏  举报