【代码】C语言|保留小数点后n位并四舍五入,便于处理运算和存储不善的浮点数

您所在的位置:网站首页 c语言如何将三位数取倒转为一位数 【代码】C语言|保留小数点后n位并四舍五入,便于处理运算和存储不善的浮点数

【代码】C语言|保留小数点后n位并四舍五入,便于处理运算和存储不善的浮点数

2024-07-02 15:55| 来源: 网络整理| 查看: 265

前言

有个人跟我说浮点数运算起来非常麻烦,总是算着算着丢失精度,导致计算结果取int的时候取不准。毕竟系统也没有自动根据这个数的精度四舍五入的功能。 比如int(2.999999999999999)=2,但是float(2.999999999999999)=3.000000。

我觉得这个问题很好解决,正好网上一搜这个问题的答主并没有给出完整且正常的代码,只提到了可以用“round”处理,或者自己手搓了一个round,让我震撼。所以我就简单写了一下这篇博客。

文章目录 前言小数点后n位取整的思路思路1 利用round思路实现思路的优势和问题 思路2 利用字符串相关函数处理思路实现思路优势和问题 思路3 利用float降低精度思路实现思路优势和问题

小数点后n位取整的思路 思路1 利用round 思路实现 round这个函数在这个问题里的作用:round只能对小数点后面那一位做四舍五入,没办法舍入第n位。但是我们可以利用这个特性去做。直观的思路简述:int(float(val,n),10),意思是取n位小数的val的值,然后转成int,从而完成满足n精度要求的int整型转换。

代码我让gpt给我写了一下:

在这里插入图片描述

可用的代码如下:

#include #include double roundToNDecimalPlaces(double num, int n) { double factor = pow(10, n); return round(num * factor) / factor; } int main() { double num = 9.99999999; int n = 3; double result = roundToNDecimalPlaces(num, n); printf("Result: %.3f\n", result); return 0; }

编译方式(需要通过在编译命令中添加 -lm 选项来链接数学库):

gcc test_round.c -o test_round -lm

运行结果就是Result: 10.000。

当然,你如果希望简洁一点,也可以把代码写成:int(round(val*pow(10,n)/pow(10,n)))。

思路的优势和问题

优势:能实现n位存储精度。 问题:pow的数值过大的时候会超过double的有效数字表示能力。很多时候pow(10,5)就会溢出了。

思路2 利用字符串相关函数处理 思路实现

思路2这个思路比较清奇,是我随便想的。

思路来源:字符串可以做截断;思路简述:int(str(float(vv)),10),就是利用sprintf的功能先转成str,然后取str的那几位再int向下取整。

照旧是让GPT写的,提问过程就不截图了,具体代码如下:

#include #include double roundToNDecimalPlaces(double num, int n) { char format[20]; sprintf(format, "%%.%df", n); // 构造格式字符串,保留n位小数 char str[50]; sprintf(str, format, num); // 将浮点数转换为字符串 return atof(str); // 将字符串转换回浮点数 } int main() { double num = 9.99999999; int n = 3; double result = roundToNDecimalPlaces(num, n); printf("Result: %.3f\n", result); return 0; }

运行结果就是Result: 10.000。

思路优势和问题

优势:能充分利用现有的计算机制,并且能够达到任意高的存储精度要求。 缺点:有的实现里面可能无法调用sprintf这个函数,并且sprintf这个函数运算速度不是很快。

思路3 利用float降低精度 思路实现

思路3是脱胎于思路1的。

思路核心:float的精度比double低思路简述:int(float(val))。就是先把double类型的val数据强制转换为float给它丢失一下精度,然后再转int。这个实现思路只能保证float这么大的精度大小。

实现代码:

#include int roundToFloat(double num) { return (int)(float)num; } int main() { double num = 9.9999999; float temp = (float)num; int result = roundToFloat(num); printf("Temp: %f, Result: %d\n", temp, result); return 0; }

运行结果:Temp: 10.000000, Result: 10。

思路优势和问题

优势:算得超级快。 问题:只能满足float这种精度要求。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3