如何编写一个 四舍五入(4舍5入) 的函数(使用C语言)

实例

float halfAdjust(float num, int KeepNDecimalPlace)
{
   
	int i = 0;
	int j = 1;
	
	while( i < KeepNDecimalPlace )
	{
   
		j *= 10;
		i++;
	}
	
	num = 1.0*((int)(num*j + 0.5))/j;

	return num;
}

int main(void)
{
   
	printf("%f\n", halfAdjust(1.12345, 0));
	printf("%f\n", halfAdjust(1.12345, 1));
	printf("%f\n", halfAdjust(1.12345, 2));
	printf("%f\n", halfAdjust(1.12345, 3));
	printf("%f\n", halfAdjust(1.12345, 4));
	printf("%f\n", halfAdjust(1.12345, 5));

	return 0;
}

怎么来的呢?

拉个最简单的案例吧!

我有二个数字其中一个是 1.4,另一个是1.5

注意到了吗,上面两个都是浮点类型,如果我直接给他们强转成int型会这么样呢?
上代码

int main(void)
{
   
	float aa = 1.4;
	float bb = 1.5;
	int cc = (int)aa;
	int dd = (int)bb;
	
	printf("%f\n", cc);
	printf("%f\n", dd);
	
	return 0;
}

输出1
发现了吧,他们都会被消去小数部分,这个叫做向下对齐,不管你后面小数是多少都会被直接消去。

那我们如果想要利用这个特性达到四舍五入,怎么做?嘿嘿,聪明的同学已经想到了,直接加上一个0.5就可以啦!上代码看看。

int main(void)
{
   
	float aa = 1.4;
	float bb = 1.5;
	int cc = (int)(aa+0.5);
	int dd = (int)(bb+0.5);
	
	printf("%f\n", cc);
	printf("%f\n", dd);
	
	return 0;
}

输出2
为什么呢?1.5+0.5就变成2啦,再怎么消去小数部分也还是2呀;
而1.4+0.5就是1.9,而1.9被消去小数就直接变成1了。

好啦以上就是保留0位小数。

怎么保留多位小鼠呢?

仔细看看我的函数中的这个代码:

num = 1.0*((int)(num*j + 0.5))/j;

假如输入的num是1.5,而 j 先不管,直接为1,那么就是这个形式:

num = 1.0*((int)(1.5 + 0.5));

其中的 (int)(1.5 + 0.5) 不就是直接转换成保留0位小数吗!

那么那个刚刚被我们省略掉的 j ,又是什么呢?

假如我们有一个数字为1.45,其中 j 为10,那么就变成这个形式:

num = 1.0*((int)(1.45*10 + 0.5))/10;
num = 1.0*((int)(14.5 + 0.5))/10;
num = 1.0*15/10;
num = 1.5

看出来了吗,这个就是保留1位小数,很简单吧先把数字乘上10,再按照保留0位小数来算,最后除以10归位。

而2位小数时的 j = 100; 10的2次幂
而3位小数时的 j = 1000; 10的3次幂
依此类推。

这个时候就知道我的函数中的,这一部分怎么来的了吧:

while( i < KeepNDecimalPlace )
{
   
	j *= 10;
	i++;
}

就是为了吧 j 变为对应的10的幂次去。

以上的保留小数有什么缺陷

缺陷描述

缺陷大大的有!

你看!

我有两个数字

1.45和1.44

本来做0位的四舍五入,应该变成2和1才对。
但是却变成了如下的结果:
输出3
为什么?你看:
1.45+0.5 = 1.95
1.44+0.5 = 1.94

这个两个值都小于2,直接强转成int型时会直接变成1。。。

怎么解决这个问题呢?

嘿嘿,这个解决可以是广义的解决,也可以是狭义的解决。
好!先别管广义和狭义的意思,我们先这样:

我想保留1位小数,但我的数字有两位小数,这个时候就可以这样:
1.45+0.55 = 2
1.44+0.55 = 1.99
哈哈哈,我直接把加上0.5变成加上0.55,这么样,解决了吧!
这个就是狭义的解决。



广义的解决就是把问题的所有可能性都快给他解决掉了,这个我还没有思路。。。
总不能加上0.555555555555吧。。。
请有思路的同学在评论区告诉我。。。

评论区(hhh):

我已经有思路了,但奈何这个代码区域写不下了。
我简单告诉你,通过while循环不断
比较num的小数部分和0.5之间的大小;
比较num*10的小数部分和0.5之间的大小;
比较num*100的小数部分和0.5之间的大小;
比较num*1000的小数部分和0.5之间的大小;

好了完结了。。。虽然不那么完美啦!

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-10 15:06:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-10 15:06:02       106 阅读
  3. 在Django里面运行非项目文件

    2023-12-10 15:06:02       87 阅读
  4. Python语言-面向对象

    2023-12-10 15:06:02       96 阅读

热门阅读

  1. ClickHouse为何如此之快

    2023-12-10 15:06:02       61 阅读
  2. qt:使用信号槽机制传参

    2023-12-10 15:06:02       63 阅读
  3. 数据结构之内部排序

    2023-12-10 15:06:02       44 阅读
  4. pandas常见问题汇总

    2023-12-10 15:06:02       63 阅读
  5. 使用python实现断点续传

    2023-12-10 15:06:02       48 阅读
  6. 特权FPGA学习笔记

    2023-12-10 15:06:02       55 阅读
  7. s3-dist-cp 介绍教程示例使用方法

    2023-12-10 15:06:02       49 阅读
  8. 机器人IC

    2023-12-10 15:06:02       48 阅读
  9. Spark DataFrame和Dataset使用例子

    2023-12-10 15:06:02       60 阅读