【C/C++】四舍五入、向上取整、向下取整、精确取整
IEEE 754 - 维基百科,自由的百科全书 (wikipedia.org)
数值修约 - 维基百科,自由的百科全书 (wikipedia.org)
IEEE 754标准规定了浮点数的舍入方式:
-
就近舍入:
- 即十进制下的四舍五入方式。
- 对于二进制表示的浮点数,小数位会根据以下规则进行处理:
- 如果小数数字是1001,大于0.5,则最低位进1。
- 如果小数数字是0111,小于0.5,则直接舍掉小数数字。
- 如果小数数字是1000,正好等于0.5的特殊情况;此时,最低位为0则舍掉多余位,最低位为1则进位1。
-
朝0舍入:
- 即朝数轴零点方向舍入,直接截尾即可。
-
朝正无穷舍入:
- 对正数而言,小数位全为0则直接截尾,不全为0则向最低有效位进1。
- 对负数而言,不管小数位是多少,直接截尾即可。
-
朝负无穷舍入:
- 对负数而言,小数位全为0则直接截尾,不全为0则向最低有效位进1。
- 对正数而言,不管小数位是多少,直接截尾即可。
格式符 %f,%.nf 默认是四舍五入
#include<stdio.h> #define BUF_SIZE (100) int main() { char buf[BUF_SIZE]; printf("%f, %.6f, %f, %.6f\n", 1.23456789, 1.23456789, 1.23456712, 1.23456712); snprintf(buf, BUF_SIZE, "%f, %.6f, %f, %.6f", 1.23456789, 1.23456789, 1.23456712, 1.23456712); printf("%s\n", buf); return 0; } // 结果 1.234568, 1.234568, 1.234567, 1.234567 1.234568, 1.234568, 1.234567, 1.234567
C代码实现
#include <stdio.h> double _pow(double base, int exponent) { double result = 1.0; if (exponent >= 0) { for (int i = 0; i < exponent; i++) { result *= base; } } else { for (int i = 0; i < -exponent; i++) { result /= base; } } return result; } /** * @brief 向下取整(变异朝负无穷舍入) * * @param bit 精确到第几位,>0 操作小数位,≤0 操作整数位 * @note 检查精确位后的第一个位数 */ double _floor_bit(double num, int bit) { double times = _pow(10, bit); int int_part = (int)(num * times); // 检查要求精确位数的后一位是否为0,不为0负数要减一 if (num < 0 && (int)(num*times*10)/10.0 != int_part) { return (double)(int_part - 1) / times; } else { return (double)int_part / times; } } /** * @brief 向上取整(变异朝正无穷舍入) * * @param bit 精确到第几位 */ double _ceil_bit(double num, int bit) { double times = _pow(10, bit); int int_part = (int)(num * times); // 检查要求精确位数的后一位是否为0,不为0正数要加一 if (num > 0 && (int)(num*times*10)/10.0 != int_part) { return (double)(int_part + 1) / times; } else { return (double)int_part / times; } } /** * @brief 四舍五入(就近舍入) * * @param bit 精确到第几位 */ double _round_bit(double num, int bit) { return num < 0 ? _ceil_bit(num - 0.5/_pow(10, bit), bit) : _floor_bit(num + 0.5/_pow(10, bit), bit); } /** * @brief 精确到位(朝0舍入) * * @param bit 精确到第几位 * @note 截断精确位后的数字 */ double _truncate_bit(double num, int bit) { return num < 0 ? _ceil_bit(num, bit) : _floor_bit(num, bit); } void test_bit(double num, int bit) { printf("** %s(%f, %d)\n", __func__, num, bit); double result_floor = _floor_bit(num, bit); printf("向下取整的结果为: %lf\n", result_floor); double result_ceil = _ceil_bit(num, bit); printf("向上取整的结果为: %lf\n", result_ceil); double result_round = _round_bit(num, bit); printf("四舍五入的结果为: %lf\n", result_round); double result_truncate = _truncate_bit(num, bit); printf("精确到位的结果为: %lf\n\n", result_truncate); } /** * @brief 向下取整(朝负无穷舍入) * * @param bit 精确到第几位 * @note 检查精确位后的所有位数 */ double _floor(double num, int bit) { double times = _pow(10, bit); int int_part = (int)(num * times); if (num < 0 && num * times != int_part) { return (int_part - 1) / times; } else { return int_part / times; } } /** * @brief 向上取整(朝正无穷舍入) * * @param bit 精确到第几位 * @note 检查精确位后的所有位数 */ double _ceil(double num, int bit) { double times = _pow(10, bit); int int_part = (int)(num * times); if (num > 0 && num * times != int_part) { return (int_part + 1) / times; } else { return int_part / times; } } /** * @brief 四舍五入(就近舍入) * * @param bit 精确到第几位 */ double _round(double num, int bit) { return num < 0 ? _ceil(num - 0.5/_pow(10, bit), bit) : _floor(num + 0.5/_pow(10, bit), bit); } /** * @brief 精确到位(朝0舍入) * * @param bit 精确到第几位 * @note 截断精确位后的数字 */ double _truncate(double num, int bit) { return num < 0 ? _ceil(num, bit) : _floor(num, bit); } void test(double num, int bit) { printf("** %s(%f, %d)\n", __func__, num, bit); double result_floor = _floor(num, bit); printf("向下取整的结果为: %lf\n", result_floor); double result_ceil = _ceil(num, bit); printf("向上取整的结果为: %lf\n", result_ceil); double result_round = _round(num, bit); printf("四舍五入的结果为: %lf\n", result_round); double result_truncate = _truncate(num, bit); printf("精确到位的结果为: %lf\n\n", result_truncate); } int main(void) { int bit = 0; double num = 12300.000001; test(num, bit); test_bit(num, bit); num = -12300.000001; test(num, bit); test_bit(num, bit); num = 6.0; test_bit(num, bit); num = -6.0; test_bit(num, bit); num = 6.111; test_bit(num, bit); num = -6.111; test_bit(num, bit); num = 6.888; test_bit(num, bit); num = -6.888; test_bit(num, bit); num = 6.555; test_bit(num, bit); num = -6.555; test_bit(num, bit); num = 6.405; test_bit(num, bit); num = -6.405; test_bit(num, bit); num = 6.415; test_bit(num, bit); num = -6.415; test_bit(num, bit); num = 6.455; test_bit(num, bit); num = -6.455; test_bit(num, bit); num = 6.465; test_bit(num, bit); num = -6.465; test_bit(num, bit); return 0; }
执行结果
bit | -1 | 0 | 2 |
结果 |
** test(12300.000001, -1) ** test_bit(12300.000001, -1) ** test(-12300.000001, -1) ** test_bit(-12300.000001, -1) ** test_bit(6.000000, -1) ** test_bit(-6.000000, -1) ** test_bit(6.111000, -1) ** test_bit(-6.111000, -1) ** test_bit(6.888000, -1) ** test_bit(-6.888000, -1) ** test_bit(6.555000, -1) ** test_bit(-6.555000, -1) ** test_bit(6.405000, -1) ** test_bit(-6.405000, -1) ** test_bit(6.415000, -1) ** test_bit(-6.415000, -1) ** test_bit(6.455000, -1) ** test_bit(-6.455000, -1) ** test_bit(6.465000, -1) ** test_bit(-6.465000, -1) |
** test(12300.000001, 0) ** test_bit(12300.000001, 0) ** test(-12300.000001, 0) ** test_bit(-12300.000001, 0) ** test_bit(6.000000, 0) ** test_bit(-6.000000, 0) ** test_bit(6.111000, 0) ** test_bit(-6.111000, 0) ** test_bit(6.888000, 0) ** test_bit(-6.888000, 0) ** test_bit(6.555000, 0) ** test_bit(-6.555000, 0) ** test_bit(6.405000, 0) ** test_bit(-6.405000, 0) ** test_bit(6.415000, 0) ** test_bit(-6.415000, 0) ** test_bit(6.455000, 0) ** test_bit(-6.455000, 0) ** test_bit(6.465000, 0) ** test_bit(-6.465000, 0) |
** test(12300.000001, 2) ** test_bit(12300.000001, 2) ** test(-12300.000001, 2) ** test_bit(-12300.000001, 2) ** test_bit(6.000000, 2) ** test_bit(-6.000000, 2) ** test_bit(6.111000, 2) ** test_bit(-6.111000, 2) ** test_bit(6.888000, 2) ** test_bit(-6.888000, 2) ** test_bit(6.555000, 2) ** test_bit(-6.555000, 2) ** test_bit(6.405000, 2) ** test_bit(-6.405000, 2) ** test_bit(6.415000, 2) ** test_bit(-6.415000, 2) ** test_bit(6.455000, 2) ** test_bit(-6.455000, 2) ** test_bit(6.465000, 2) ** test_bit(-6.465000, 2) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
2019-03-08 【rt-thread 】组件与设备初始化配置
2018-03-08 【CPU】判断机器大小端的两种实现方法