惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
Stack Overflow Blog
Stack Overflow Blog
B
Blog RSS Feed
C
Check Point Blog
D
Docker
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
Google DeepMind News
Google DeepMind News
MongoDB | Blog
MongoDB | Blog
博客园_首页
Apple Machine Learning Research
Apple Machine Learning Research
量子位
有赞技术团队
有赞技术团队
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
D
DataBreaches.Net
M
MIT News - Artificial intelligence
B
Blog
阮一峰的网络日志
阮一峰的网络日志
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
腾讯CDC
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
V2EX
月光博客
月光博客

又见苍岚

COLMAP PatchMatch Stereo 算法详解 事件驱动的状态机框架:从理论到工程实践 Git 在国内网络环境下无法 Push 的排查与修复 —— 配置 Clash 代理 分段五次多项式插值原理详解 路径插值方法深度对比研究 Claude Code 使用指南 OpenClaw 记忆管理与技能创建指南 CBS(Conflict-Based Search)算法详解 A* 算法及其变种详解 OpenClaw 配置多 Agents Windows Powershell 无法加载文件,因为在此系统上禁止运行脚本问题的解决方案 MaxClaw 安装流程 大模型 AI 名词介绍 AList 网盘聚合工具简介 Protobuf 简介与测试 Claude Code 简介以及 GLM 4.7 模型接入 Github 歌词下载工具 163MusicLyrics Python __getattr__ 懒加载 Python TypedDict 机器人仿真平台 Gazebo 安装记录 机器人仿真平台 Gazebo 简介 多机器人路径规划问题(Multi-Agent Path Finding, MAPF)简介 Python exifread 读取修改过的 jpeg 信息错误问题修复 3D 坐标系变换的理解 3D 旋转矩阵基本概念 MongoDB Compass 介绍 Python 环境管理工具 uv Flutter 开发指南 Snipaste 安装下载与黑屏问题解决方案 全局路径规划算法记录
Python 四舍五入
Yiwei Zhang · 2024-08-23 · via 又见苍岚

在进行数字剪裁操作时,四舍五入事实上有多种方式,本文记录相关内容以及 Python 实现。

四舍五入

本是很简单的道理,在实际使用过程中发现有些细节上的不同。

标准的四舍五入

  1. 舍入到整数

    • 如果小数部分小于0.5,则舍去小数部分,保留整数部分。
    • 如果小数部分大于或等于0.5,则将整数部分加1。

    例如:

    • 3.2 四舍五入到整数是 3。
    • 3.7 四舍五入到整数是 4。
  2. 舍入到指定的小数位数

    • 对于需要舍入的位数右侧的第一位数字(即“决定位”),如果它小于5,则舍去它和它右侧的所有数字。
    • 如果“决定位”大于或等于5,则舍去它和它右侧的所有数字,并将“决定位”前一位数字加1。

    例如:

    • 3.141592653589 四舍五入到两位小数是 3.14。
    • 3.141592653589 四舍五入到三位小数是 3.142。

特殊的四舍五入

  1. 向偶数舍入(Bankers’ rounding)

    • 当“决定位”恰好是5时,检查“决定位”前一位数字(即“保留位”)是奇数还是偶数。
    • 如果“保留位”是奇数,则将“保留位”加1(向上舍入)。
    • 如果“保留位”是偶数,则舍去“决定位”及其右侧的所有数字(向下舍入)。

    例如:

    • 2.5 向偶数舍入到整数是 2。
    • 3.5 向偶数舍入到整数是 4。
  2. 向上舍入

    • 不论“决定位”是什么数字,总是将数值舍入到比它大的最接近的整数或小数位数。

    例如:

    • 2.1 向上舍入到整数是 3。
  3. 向下舍入

    • 不论“决定位”是什么数字,总是将数值舍入到比它小的最接近的整数或小数位数。

    例如:

    • 2.9 向下舍入到整数是 2。

Python

python 3.11.7 在四舍五入这里实现的很奇怪:

round

说到 Python 自带的 round 我真的是很无语:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
>>> round(5.5155555, 6)
5.515555
>>> round(5.5055555, 6)
5.505555
>>> round(5.5255555, 6)
5.525556
>>> round(5.5355555, 6)
5.535556
>>> round(5.5455555, 6)
5.545555
>>> round(5.5455555, 6)
5.545555
>>> round(5.5555555, 6)
5.555555
>>> round(5.5655555, 6)
5.565556
>>> round(5.5755555, 6)
5.575556
>>> round(5.5855555, 6)
5.585555
>>> round(5.5955555, 6)
5.595555

这已经没法用什么四舍五入的规则解释了,整个一个乱搞。

np.round

好一些,不过也有解释不了的事

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>> np.round(5.155555,5)
5.15555
>>> np.round(5.255555,5)
5.25556
>>> np.round(5.355555,5)
5.35556
>>> np.round(5.455555,5)
5.45556
>>> np.round(5.555555,5)
5.55556
>>> np.round(5.655555,5)
5.65556
>>> np.round(5.755555,5)
5.75556
>>> np.round(5.855555,5)
5.85556
>>> np.round(5.955555,5)
5.95556
>>> np.round(5.055555,5)
5.05556

不知道 5.1为啥就不进到偶数去

decimal

用法稍微复杂一点,但是靠谱的时候多一些:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import decimal
from decimal import Decimal

decimal.getcontext().prec = 6
quant = decimal.Decimal('0.00001')

for i in range(10):
value_str = '5.0' + str(i) + '55555'
value = Decimal(value_str)
rounded_value = value.quantize(quant)
print(rounded_value)

-->
5.00556
5.01556
5.02556
5.03556
5.04556
5.05556
5.06556
5.07556
5.08556
5.09556

相对来说靠谱很多,而且提供了四舍五入的选项:

  • decimal.ROUND_CEILING:向正无穷大舍入。
  • decimal.ROUND_FLOOR:向负无穷大舍入。
  • decimal.ROUND_DOWN:向零舍入。
  • decimal.ROUND_UP:远离零舍入。
  • decimal.ROUND_HALF_UP:四舍五入,5进位。
  • decimal.ROUND_HALF_DOWN:四舍五入,5舍去。
  • decimal.ROUND_HALF_EVEN:四舍五入,5向最近的偶数舍入。

但是我在一次实验中还是发现了不正确的四舍五入,暂时没有复现,使用的时候还是要多加小心。

文章链接:
https://www.zywvvd.com/notes/coding/python/python-round/pytho-round/