【代码】C语言|保留小数点后n位并四舍五入,便于处理运算和存储不善的浮点数
前言
有个人跟我说浮点数运算起来非常麻烦,总是算着算着丢失精度,导致计算结果取int的时候取不准。毕竟系统也没有自动根据这个数的精度四舍五入的功能。
比如int(2.999999999999999)=2,但是float(2.999999999999999)=3.000000。
我觉得这个问题很好解决,正好网上一搜这个问题的答主并没有给出完整且正常的代码,只提到了可以用“round”处理,或者自己手搓了一个round,让我震撼。所以我就简单写了一下这篇博客。
文章目录
小数点后n位取整的思路
思路1 利用round
思路实现
- round这个函数在这个问题里的作用:round只能对小数点后面那一位做四舍五入,没办法舍入第n位。但是我们可以利用这个特性去做。
- 直观的思路简述:
int(float(val,n),10),意思是取n位小数的val的值,然后转成int,从而完成满足n精度要求的int整型转换。
代码我让gpt给我写了一下:

可用的代码如下:
#include <stdio.h>
#include <math.h>
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 <stdio.h>
#include <stdlib.h>
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 <stdio.h>
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这种精度要求。
【代码】C语言|保留小数点后n位并四舍五入,便于处理运算和存储不善的浮点数的更多相关文章
- 实现js保留小数点后N位的代码
在JS中,一般实现保留小数点后N位的话,都是利用toFixed函数 <script language="javascript"> document.write(&quo ...
- php number_format()保留小数点后几位
[PHP_保留两位小数的相关函数] php保留两位小数并且四舍五入 Php代码 1 $num = 123213.666666; 2 echo sprintf("%.2f ...
- js保留小数点后N位的方法介绍
js保留小数点后N位的方法介绍 利用toFixed函数 代码如下 复制代码 <script language="javascript"> document.write( ...
- 格式化 float 类型,保留小数点后1位
""" 练习 : 小明的成绩从去年的72分提升到了今年的85分,请计算小明成绩提升的百分点, 并用字符串格式化显示出'xx.x%',只保留小数点后1位: &qu ...
- 关于Oracle中查询的数字值的显示格式需要保留小数点后两位(或者三位,及其他位数)
关于Oracle中查询的数字值的显示格式需要保留小数点后两位(或者三位,及其... 方法一:使用to_char的fm格式,即: to_char(round(data.amount,2),'FM9999 ...
- input内强制保留小数点后两位 位数不足时自动补0
input内强制保留小数点后两位 位数不足时自动补0 小数点后位数超出2位时进行四舍五入 需引入jquery包 1.11.2版本 1 function xiaoshu(x) 2 { 3 var f = ...
- JAVA除法保留小数点后两位的两种方法 Java Math的 floor,round和ceil的总结
floor 返回不大于的最大整数 round 则是4舍5入的计算,入的时候是到大于它的整数round方法,它表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下 ...
- php number_format()保留小数点后几位有效数的函数 千位分组来格式化数字(转)
PHP保留小数点后2位的函数number_format number_format(带小数点的书,小数点后保留的位数) number_format(8.3486,2); //取得小数点后2位有效数/ ...
- C#保留小数点后几位
String.Format("{0:N1}", a) 保留小数点后一位 String.Format("{0:N2}", a) 保留小数点后两位 String.F ...
- Javascript 智能输入数字且保留小数点后三位
html: <input type="text" name="cprice" placeholder="最多保留小数点后三位" onk ...
随机推荐
- 管理虚拟机(libvirt)
给我的理解就是与用户交互的"显示器" [root@kvm1 ~]# systemctl status libvirtd [root@kvm1 ~]# virsh virsh # l ...
- .Net Core 项目启动方式
本文篇幅较小,讲解如何通过命令行启动项目 接着上一章的Core WebApi(https://www.cnblogs.com/zousc/p/12420998.html),我们已经有了Hello这个控 ...
- JUC并发—6.AQS源码分析二
大纲 1.ReentractReadWriteLock的基本原理 2.基于AQS实现的ReentractReadWriteLock 3.ReentractReadWriteLock如何竞争写锁 4.R ...
- 割以咏志:Stoer–Wagner 算法求解全局最小割
全局最小割问题(Global Min-Cut Problem)是图论中的一个经典问题,旨在通过切割图中的边来划分图的顶点集合.具体来说,给定一个加权无向图 $ G = (V, E) $,图中每条边 $ ...
- Trae初体验
前情 自从AI IDE面世以来,网络上到处流传程序员要失业了,小白也能轻松完成程序开发了,某某0基础靠AI上架了苹果应用,平时工作也有偶尔用用AI工具的我,都觉得这些都是标题党文章不予理会的,直到看到 ...
- Python - 程序体验
CASE:输入某年某月某日,判断这一天是这一年的第几天? # 输入某年某月某日, 判断这一天是这一年的第几天? import datetime dtstr = input('Enter the dat ...
- 机器学习 | 强化学习(6) | 策略梯度方法(Policy Gradient Method)
6-策略梯度方法(Policy Gradient Method) 策略梯度概论(Introduction) 基于策略(Policy-Based) 的强化学习 对于上一节课(价值函数拟合)中采用参数\( ...
- 【练习回顾】DS前三次作业
第一次作业 T2.基本计算器 使用了数组栈--数字栈和符号栈 T5.全排列输出(permutation) 使用了标准写法--字典序算法 void reverse(int left,int right) ...
- laravel-echo-server 启动报错 [ioredis] Unhandled error event: ReplyError: NOAUTH Authentication required.
可以在 .env 文件加上以下配置 LARAVEL_ECHO_SERVER_REDIS_HOST= LARAVEL_ECHO_SERVER_REDIS_PASSWORD= LARAVEL_ECHO_S ...
- C#通过FTP获取服务端文件
一.简介 实际需求是在前端修改了配置文件后,由上位机统一分发给所有设备,因为下位机支持FTP协议,因此选用FTP来实现文件传输功能. 二.准备工作 1.FTP服务搭建 FTP服务端选用FileZi ...