【C/C++】四舍五入、向上取整、向下取整、精确取整

IEEE 754 - 维基百科,自由的百科全书 (wikipedia.org)

数值修约 - 维基百科,自由的百科全书 (wikipedia.org)

IEEE-754 在线浮点数转换

IEEE 754标准规定了浮点数的舍入方式:

  1. 就近舍入

    • 即十进制下的四舍五入方式。
    • 对于二进制表示的浮点数,小数位会根据以下规则进行处理:
      • 如果小数数字是1001,大于0.5,则最低位进1。
      • 如果小数数字是0111,小于0.5,则直接舍掉小数数字。
      • 如果小数数字是1000,正好等于0.5的特殊情况;此时,最低位为0则舍掉多余位,最低位为1则进位1。
  2. 朝0舍入

    • 即朝数轴零点方向舍入,直接截尾即可。
  3. 朝正无穷舍入

    • 对正数而言,小数位全为0则直接截尾,不全为0则向最低有效位进1。
    • 对负数而言,不管小数位是多少,直接截尾即可。
  4. 朝负无穷舍入

    • 对负数而言,小数位全为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)
向下取整的结果为: 12300.000000
向上取整的结果为: 12310.000000
四舍五入的结果为: 12300.000000
精确到位的结果为: 12300.000000

** test_bit(12300.000001, -1)
向下取整的结果为: 12300.000000
向上取整的结果为: 12300.000000
四舍五入的结果为: 12300.000000
精确到位的结果为: 12300.000000

** test(-12300.000001, -1)
向下取整的结果为: -12310.000000
向上取整的结果为: -12300.000000
四舍五入的结果为: -12300.000000
精确到位的结果为: -12300.000000

** test_bit(-12300.000001, -1)
向下取整的结果为: -12300.000000
向上取整的结果为: -12300.000000
四舍五入的结果为: -12300.000000
精确到位的结果为: -12300.000000

** test_bit(6.000000, -1)
向下取整的结果为: 0.000000
向上取整的结果为: 10.000000
四舍五入的结果为: 10.000000
精确到位的结果为: 0.000000

** test_bit(-6.000000, -1)
向下取整的结果为: -10.000000
向上取整的结果为: 0.000000
四舍五入的结果为: -10.000000
精确到位的结果为: 0.000000

** test_bit(6.111000, -1)
向下取整的结果为: 0.000000
向上取整的结果为: 10.000000
四舍五入的结果为: 10.000000
精确到位的结果为: 0.000000

** test_bit(-6.111000, -1)
向下取整的结果为: -10.000000
向上取整的结果为: 0.000000
四舍五入的结果为: -10.000000
精确到位的结果为: 0.000000

** test_bit(6.888000, -1)
向下取整的结果为: 0.000000
向上取整的结果为: 10.000000
四舍五入的结果为: 10.000000
精确到位的结果为: 0.000000

** test_bit(-6.888000, -1)
向下取整的结果为: -10.000000
向上取整的结果为: 0.000000
四舍五入的结果为: -10.000000
精确到位的结果为: 0.000000

** test_bit(6.555000, -1)
向下取整的结果为: 0.000000
向上取整的结果为: 10.000000
四舍五入的结果为: 10.000000
精确到位的结果为: 0.000000

** test_bit(-6.555000, -1)
向下取整的结果为: -10.000000
向上取整的结果为: 0.000000
四舍五入的结果为: -10.000000
精确到位的结果为: 0.000000

** test_bit(6.405000, -1)
向下取整的结果为: 0.000000
向上取整的结果为: 10.000000
四舍五入的结果为: 10.000000
精确到位的结果为: 0.000000

** test_bit(-6.405000, -1)
向下取整的结果为: -10.000000
向上取整的结果为: 0.000000
四舍五入的结果为: -10.000000
精确到位的结果为: 0.000000

** test_bit(6.415000, -1)
向下取整的结果为: 0.000000
向上取整的结果为: 10.000000
四舍五入的结果为: 10.000000
精确到位的结果为: 0.000000

** test_bit(-6.415000, -1)
向下取整的结果为: -10.000000
向上取整的结果为: 0.000000
四舍五入的结果为: -10.000000
精确到位的结果为: 0.000000

** test_bit(6.455000, -1)
向下取整的结果为: 0.000000
向上取整的结果为: 10.000000
四舍五入的结果为: 10.000000
精确到位的结果为: 0.000000

** test_bit(-6.455000, -1)
向下取整的结果为: -10.000000
向上取整的结果为: 0.000000
四舍五入的结果为: -10.000000
精确到位的结果为: 0.000000

** test_bit(6.465000, -1)
向下取整的结果为: 0.000000
向上取整的结果为: 10.000000
四舍五入的结果为: 10.000000
精确到位的结果为: 0.000000

** test_bit(-6.465000, -1)
向下取整的结果为: -10.000000
向上取整的结果为: 0.000000
四舍五入的结果为: -10.000000
精确到位的结果为: 0.000000

** test(12300.000001, 0)
向下取整的结果为: 12300.000000
向上取整的结果为: 12301.000000
四舍五入的结果为: 12300.000000
精确到位的结果为: 12300.000000

** test_bit(12300.000001, 0)
向下取整的结果为: 12300.000000
向上取整的结果为: 12300.000000
四舍五入的结果为: 12300.000000
精确到位的结果为: 12300.000000

** test(-12300.000001, 0)
向下取整的结果为: -12301.000000
向上取整的结果为: -12300.000000
四舍五入的结果为: -12300.000000
精确到位的结果为: -12300.000000

** test_bit(-12300.000001, 0)
向下取整的结果为: -12300.000000
向上取整的结果为: -12300.000000
四舍五入的结果为: -12300.000000
精确到位的结果为: -12300.000000

** test_bit(6.000000, 0)
向下取整的结果为: 6.000000
向上取整的结果为: 6.000000
四舍五入的结果为: 6.000000
精确到位的结果为: 6.000000

** test_bit(-6.000000, 0)
向下取整的结果为: -6.000000
向上取整的结果为: -6.000000
四舍五入的结果为: -6.000000
精确到位的结果为: -6.000000

** test_bit(6.111000, 0)
向下取整的结果为: 6.000000
向上取整的结果为: 7.000000
四舍五入的结果为: 6.000000
精确到位的结果为: 6.000000

** test_bit(-6.111000, 0)
向下取整的结果为: -7.000000
向上取整的结果为: -6.000000
四舍五入的结果为: -6.000000
精确到位的结果为: -6.000000

** test_bit(6.888000, 0)
向下取整的结果为: 6.000000
向上取整的结果为: 7.000000
四舍五入的结果为: 7.000000
精确到位的结果为: 6.000000

** test_bit(-6.888000, 0)
向下取整的结果为: -7.000000
向上取整的结果为: -6.000000
四舍五入的结果为: -7.000000
精确到位的结果为: -6.000000

** test_bit(6.555000, 0)
向下取整的结果为: 6.000000
向上取整的结果为: 7.000000
四舍五入的结果为: 7.000000
精确到位的结果为: 6.000000

** test_bit(-6.555000, 0)
向下取整的结果为: -7.000000
向上取整的结果为: -6.000000
四舍五入的结果为: -7.000000
精确到位的结果为: -6.000000

** test_bit(6.405000, 0)
向下取整的结果为: 6.000000
向上取整的结果为: 7.000000
四舍五入的结果为: 6.000000
精确到位的结果为: 6.000000

** test_bit(-6.405000, 0)
向下取整的结果为: -7.000000
向上取整的结果为: -6.000000
四舍五入的结果为: -6.000000
精确到位的结果为: -6.000000

** test_bit(6.415000, 0)
向下取整的结果为: 6.000000
向上取整的结果为: 7.000000
四舍五入的结果为: 6.000000
精确到位的结果为: 6.000000

** test_bit(-6.415000, 0)
向下取整的结果为: -7.000000
向上取整的结果为: -6.000000
四舍五入的结果为: -6.000000
精确到位的结果为: -6.000000

** test_bit(6.455000, 0)
向下取整的结果为: 6.000000
向上取整的结果为: 7.000000
四舍五入的结果为: 6.000000
精确到位的结果为: 6.000000

** test_bit(-6.455000, 0)
向下取整的结果为: -7.000000
向上取整的结果为: -6.000000
四舍五入的结果为: -6.000000
精确到位的结果为: -6.000000

** test_bit(6.465000, 0)
向下取整的结果为: 6.000000
向上取整的结果为: 7.000000
四舍五入的结果为: 6.000000
精确到位的结果为: 6.000000

** test_bit(-6.465000, 0)
向下取整的结果为: -7.000000
向上取整的结果为: -6.000000
四舍五入的结果为: -6.000000
精确到位的结果为: -6.000000

** test(12300.000001, 2)
向下取整的结果为: 12300.000000
向上取整的结果为: 12300.010000
四舍五入的结果为: 12300.000000
精确到位的结果为: 12300.000000

** test_bit(12300.000001, 2)
向下取整的结果为: 12300.000000
向上取整的结果为: 12300.000000
四舍五入的结果为: 12300.000000
精确到位的结果为: 12300.000000

** test(-12300.000001, 2)
向下取整的结果为: -12300.010000
向上取整的结果为: -12300.000000
四舍五入的结果为: -12300.000000
精确到位的结果为: -12300.000000

** test_bit(-12300.000001, 2)
向下取整的结果为: -12300.000000
向上取整的结果为: -12300.000000
四舍五入的结果为: -12300.000000
精确到位的结果为: -12300.000000

** test_bit(6.000000, 2)
向下取整的结果为: 6.000000
向上取整的结果为: 6.000000
四舍五入的结果为: 6.000000
精确到位的结果为: 6.000000

** test_bit(-6.000000, 2)
向下取整的结果为: -6.000000
向上取整的结果为: -6.000000
四舍五入的结果为: -6.000000
精确到位的结果为: -6.000000

** test_bit(6.111000, 2)
向下取整的结果为: 6.110000
向上取整的结果为: 6.120000
四舍五入的结果为: 6.110000
精确到位的结果为: 6.110000

** test_bit(-6.111000, 2)
向下取整的结果为: -6.120000
向上取整的结果为: -6.110000
四舍五入的结果为: -6.110000
精确到位的结果为: -6.110000

** test_bit(6.888000, 2)
向下取整的结果为: 6.880000
向上取整的结果为: 6.890000
四舍五入的结果为: 6.890000
精确到位的结果为: 6.880000

** test_bit(-6.888000, 2)
向下取整的结果为: -6.890000
向上取整的结果为: -6.880000
四舍五入的结果为: -6.890000
精确到位的结果为: -6.880000

** test_bit(6.555000, 2)
向下取整的结果为: 6.550000
向上取整的结果为: 6.560000
四舍五入的结果为: 6.560000
精确到位的结果为: 6.550000

** test_bit(-6.555000, 2)
向下取整的结果为: -6.560000
向上取整的结果为: -6.550000
四舍五入的结果为: -6.560000
精确到位的结果为: -6.550000

** test_bit(6.405000, 2)
向下取整的结果为: 6.400000
向上取整的结果为: 6.410000
四舍五入的结果为: 6.410000
精确到位的结果为: 6.400000

** test_bit(-6.405000, 2)
向下取整的结果为: -6.410000
向上取整的结果为: -6.400000
四舍五入的结果为: -6.410000
精确到位的结果为: -6.400000

** test_bit(6.415000, 2)
向下取整的结果为: 6.410000
向上取整的结果为: 6.420000
四舍五入的结果为: 6.420000
精确到位的结果为: 6.410000

** test_bit(-6.415000, 2)
向下取整的结果为: -6.420000
向上取整的结果为: -6.410000
四舍五入的结果为: -6.420000
精确到位的结果为: -6.410000

** test_bit(6.455000, 2)
向下取整的结果为: 6.450000
向上取整的结果为: 6.460000
四舍五入的结果为: 6.460000
精确到位的结果为: 6.450000

** test_bit(-6.455000, 2)
向下取整的结果为: -6.460000
向上取整的结果为: -6.450000
四舍五入的结果为: -6.460000
精确到位的结果为: -6.450000

** test_bit(6.465000, 2)
向下取整的结果为: 6.460000
向上取整的结果为: 6.470000
四舍五入的结果为: 6.470000
精确到位的结果为: 6.460000

** test_bit(-6.465000, 2)
向下取整的结果为: -6.470000
向上取整的结果为: -6.460000
四舍五入的结果为: -6.470000
精确到位的结果为: -6.460000

posted @   壹点灵异  阅读(1768)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
历史上的今天:
2019-03-08 【rt-thread 】组件与设备初始化配置
2018-03-08 【CPU】判断机器大小端的两种实现方法
点击右上角即可分享
微信分享提示