zoukankan      html  css  js  c++  java
  • 格式化与四舍五入

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

    本次测试使用的编译器为 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
    ", dTestZero);
    	dTestZero = 1.3;
    	printf("0.2 %.0f
    ", dTestZero);
    	dTestZero = 1.4;
    	printf("0.3 %.0f
    ", dTestZero);
    	dTestZero = 1.5;
    	printf("0.4 %.0f
    ", dTestZero);
    	dTestZero = 1.6;
    	printf("0.5 %.0f
    ", dTestZero);
    
    	double dTest = 1.2345678;
    	printf("1.1 %4.0f
    ", dTest);
    	printf("1.2 %4.1f
    ", dTest);
    	printf("1.3 %4.2f
    ", dTest);
    	printf("1.4 %4.3f
    ", dTest);
    	printf("1.5 %4.4f
    ", dTest);
    	printf("1.6 %4.5f
    ", dTest);
    	printf("1.7 %4.6f
    ", dTest);
    
    	double dTest2 = 8.7654321;
    	printf("2.1 %4.0f
    ", dTest2);
    	printf("2.2 %4.1f
    ", dTest2);
    	printf("2.3 %4.2f
    ", dTest2);
    	printf("2.4 %4.3f
    ", dTest2);
    	printf("2.5 %4.4f
    ", dTest2);
    	printf("2.6 %4.5f
    ", dTest2);
    	printf("2.7 %4.6f
    ", dTest2);
    }
    

    输出结果如下:

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

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

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

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

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

    浮点和浮点

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

    浮点数和整数

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

    整数和整数

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

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

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

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

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

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

    小结

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

    参考文章:

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

    作者:浩天之家
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
    Top
    收藏
    关注
    评论
  • 相关阅读:
    2013年工作总结
    jquery的ajax向后台servlet传递json类型的多维数组
    web客户端通过ajaxfileupload方式上传文件
    servlet向ajax传递list数据类型,ajax向servlet传递array数据类型
    simplemodal — jquery弹出窗体插件
    【摘抄】活在当下
    unix网络编程 str_cli epoll 非阻塞版本
    unix网络编程str_cli使用epoll实现
    unix网络编程str_cli的epoll实现
    linux 建议锁和强制锁
  • 原文地址:https://www.cnblogs.com/cherishui/p/14888370.html
Copyright © 2011-2022 走看看