32 个 Python 实例彻底解析 f-String 格式化浮点数 003【推荐收藏】

科学计数法和复数的四舍五入

科学计数法通常用于表示极大或极小的数字。Python 使用 E 表示法 显示科学计数法,如下图所示。

图 1-1 科学计数法的显示方式

图 1-1 中使用科学计数法格式化了两个数字。其中,第一种形式是科学计数法的传统形式,第二种形式是 Python 的 E 表示法

格式说明符也可以用于显示科学计数法中的数字,f-string 通常使用小写字母 e 来实现科学计数法。E 表示法如例 14 所示。

1>>> f"{1234.56789:.2e}"
2(14.1'1.23e+03'
3
4>>> f"{0.00012345:.3e}"
5(14.2'1.234e-04'

例(14.1)中的精度为 .2e,因此输出结果以科学计数法显示,并四舍五入到小数点后两位。

科学计数法也可以添加宽度参数,和正常的数字格式化一样,也使用填充符满足宽度的需求。

例(14.2)中的数字非常小,因此,科学计数法将指数乘以-04。例 14 中使用 .3e 将结果显示到小数点后三位。

注意:格式说明符只是显示工具,为了保证计算结果的准确,所有计算结果仍使用原始数字。

格式说明符还可以格式化复数。复数广泛用于与振荡有关的方程。例如,作为傅里叶变换的一部分来消除真实传输中的噪声频率。

复数是由实部和虚部组成的,其中,虚部是 -1 的平方根的倍数。通常写成 a+bi 的形式,其中 a 是实部,b 是虚部。

注意:Python 使用 j 表示虚部,不是 i

尽管复数有些抽象,但仍可以使用格式说明符,详见例 15。

 1>>> value = 3.474 + 2.323j
2>>> print(
3...     f"复数 {value} 的组成如下。",
4...     f"实部为 {value.real:.2f},",
5...     f"虚部为 {value.imag:.1f},",
6...     f"约等于 {value:.0f}。",
7...     sep="\n",
8... )
9复数 (3.474+2.323j) 的组成如下。
10实部为 3.47
11虚部为 2.3
12约等于 3+2j

f-string 使用 .real 和 .imag 访问复数的实部和虚部。通过例 15 可以看出,格式化复数与格式化其他数字没有什么不同。

此外,使用格式说明符还可以格式化整个复数,即同时格式化实部和虚部。

例 15 中的 .2f 让实部保留两位小数,.1f 让虚部保留一位小数,.0f 让整个复数保留 0 位小数。

下一节将介绍 f-string 更高阶的使用方法,在继续学习之前,再做一些练习题吧。

练习题 - 格式化科学计数法与复数

练习 7:使用 value = 13579+0.0245j,编写一行代码生成如下所示的输出结果。

1>>> value = 13579+0.0245j
2>>> print(
3...     # 在此写下你的解决方案
4... )
5
6实部为 1.36E+04,虚部为 2.45E-02。 

注意,本题使用的是大写 E

如果有不明白的地方,请参阅 Python 官方文档与格式说明符相关的内容。

使用 decimal 对象减小浮点数的误差

Python 的 float 类型规定数字的存储上限是 64 位,也就是说,如果数字超过这个大小将无法准确表示。如例 16 所示。

1>>> f"{(10000000000000 / 3)}"
2'3333333333333.3335'

正确的答案应该是 3 的无限循环,但由于存储空间的限制,小数点中出现了 5。

在这种情况下,即便使用格式说明符 .2f 将输出显示到两位小数位也不能解决问题,误差仍然存在。因为之前说过,格式说明符只是设置了四舍五入的显示效果,而不是截取数字。

为了说明这个问题,我们看一下例 17。

1>>> f"{(10000000000000 / 3) + 0.6666}"
2'3333333333334.0'

例 17 显示的输出结果不准确,甚至它的整数部分都出现了错误。在此基础上继续计算将错上加错,最终结果会更不准确。

尽管浮点数运算的精度问题涉及计算机设计的底层逻辑,但为了确保计算结果的准确度,推荐使用内置的 decimal 模块。

decimal 对象提供比 float 类型更多的浮点数算术控制,能够以一致的精度执行计算,并把精度作为其计算的重心。

例 18 展示了使用 decimal 的优势。

1>>> from decimal import Decimal as D
2>>> from decimal import getcontext
3
4>>> getcontext().prec = 4
5>>> f"¥{float("0.1") + float("0.1") + float("0.1")}"
6'¥0.30000000000000004'
7
8>>> f"¥{D("0.1") + D("0.1") + D("0.1")}"
9'¥0.3'

decimal 属于 Python 的标准库,无需安装,但必须先导入 decimal 才能访问用于实例化对象的 Decimal 类。

通过大写字母 D 导入 Decimal,可以在创建实例时使用别名,让代码更简洁。

例 18 中还导入了 getcontext() 函数。在使用 Decimal 对象时,其关键属性大多是由上下文对象集中管理的,getcontext() 函数的作用就是获取上下文。

接下来,使用 getcontext() 函数的 .prec 属性设置 Decimal 对象的精度。它定义了 Decimal 对象有效数字的位数,Decimal 实例将会四舍五入以适应其精度。

如例 18 所示,在使用 float 时,输出了错误的结果。然而,在使用 Decimal 实例时,没有出现错误。

如果对精度的要求高,则应在使用格式说明符前先将字符串转换为小数(不是浮点数),以预防计算出错,因为超出精度之外的内容已经被安全地删除了。

此外,小数的精度更高,默认精度为 28 位,而浮点数只有约 16 位。

注意:使用内置的 round() 函数四舍五入 float 类型的值也可以减少误差,但使用 decimal 模块支持仅在一处修改,即可对上下文对象中多个数字的精度进行修改,并且 Decimal.quantize() 方法还提供了更多对 Decimal 对象进行四舍五入的控制方式。

在选择精度值时,可以使用警戒数(guarding figures)

例如,在计算货币时,即使计算结果只包含两位小数,但在计算过程中仍推荐使用 4 位小数,以减少四舍五入对最终结果的影响。

总的来说,在进行计算时,建议使用比显示的小数位多两位的警戒数。

通过精度和格式说明符的组合可以使用警戒数。格式说明符在 Decimal 对象中的使用方式与浮点数一样。具体实现方式如例 19 所示。

1>>> getcontext().prec = 4
2>>> f"¥{D("0.10001") + D("0.20001"):.2f}"
3'¥0.30'

开始时,先把两个包含微小误差的数字以原始形式相加。由于上下文中的精度被设置为 4 位有效数字,当每个字符串被转换为 Decimal 对象时,将会移除这些误差。然后,再使用格式说明符把计算结果显示为四舍五入的两位小数。

注意:尽管 decimal 模块对浮点数的支持很好,但仍无法彻底解决与浮点数相关的四舍五入问题。

Decimal 对象的显示如例 20 所示。

1>>> D(0.1)
2Decimal('0.1000000000000000055511151231257827021181583404541015625')

在全局精度为 4 时,预期的答案是 0.1000。但这里的精度却被忽略了,这是因为 getcontext().prec 属性仅对表达式的结果起作用,不能直接用于浮点数。在此,可以强制应用精度,只是这样写的代码有些奇怪。实现方式如例 21 所示。

1>>> D(0.1) * D(1)
2Decimal('0.1000')

用 D(0.1) 乘以 D(1),就能应用有效数字为 4 的精度。

Python 还支持更多用字符串格式化数字的方法,下一节再继续介绍。

未完待续。

虽然小编已经尽力避免错误,但本文仍可能存在 bug,欢迎读者在公众号后台进行反馈。

相关阅读

32 个 Python 实例彻底解析 f-String 格式化浮点数 001【推荐收藏】

32 个 Python 实例彻底解析 f-String 格式化浮点数 002【推荐收藏】


相关推荐

  • 浅析MySQL代价模型:告别盲目使用EXPLAIN,提前预知索引优化策略
  • 剁手党必看——转转红包使用规则与最优组合计算全解析
  • 推荐一款开源Scada,数据采集必备
  • 5.5K Star不到1秒!!!查看系统所有配置,支持所有系统
  • 数据处理不再难!用JSONCrack轻松打造炫目可视化效果!
  • 访谈Citadel CEO Ken Griffin:从哈佛宿舍到对冲基金帝国 (附全文+视频)
  • 被嫌弃的CSS的一生
  • 该死,这糟糕的心动感,AI杀疯了!
  • 云风从阿里离职,未来计划制作Windows平台的独立游戏,曾力挽《大话西游》于狂澜
  • 知名远程控制工具、TeamViewer开源替代——RustDesk已暂停国内服务
  • 1.3万字+34张图带你全面掌握高可用架构流量治理核心策略
  • 《工作的心智》共读营,诚邀你的加入
  • 浪潮信息“元脑”全面升级,定制算力、算法、数据工具,帮企业一键召唤“大模型”
  • 厉害了,numpy!!!
  • 实现十倍增长的八个关键点;女大学生从0到第三个月赚10万丨生财周报
  • Writer:企业级全栈式文字生成平台,如何对抗ChatGPT冲击?
  • 中职→专升本→上海交大研究生,孙荣臻太棒了!
  • 实时可编辑3D重建!鼠标拖拽就能控制,港大VAST浙大联合出品
  • 华为P70闪拍功能意外爆火,CTO亲自下场解读技术原理
  • 印象笔记唐毅:AI如何升级你的“第二大脑”|中国AIGC产业峰会