【Python Cookbook】S03E02 执行精确的小数计算 decimal, math.fsum()

目录

  • 问题
  • 解决方案
  • 讨论

问题

如果我们需要对小数执行精确的计算,并且不希望因为浮点数的误差带来影响,我们该怎么做?

解决方案

关于浮点数,一个人尽皆知的问题就是其无法精确地表达出所有十进制小数位,因此甚至简单的数字也会引入微小的误差。

a = 4.2
b = 2.1
print(a + b)
print((a + b) == 6.3)>>> 6.300000000000001
>>> False

而浮点数出现误差的原因,是因为在 Python 中,浮点数遵循 IEEE 754 标准,这点导致某些十进制的小数在转换为二进制数时,无法精确表示,如

# 十进制中,0.1 表示为
x = 0.1
# 但是在转换计算机的二进制时,0.1转换为
0.1 * 2 -> 整数部分0, 0.2 * 2 -> 整数部分0, 0.4 * 2 -> 整数部分0, 0.8 * 2 -> 整数部分1, 0.6 * 2 -> 整数部分1, 0.2 * 2 -> 整数部分0, ...
即b(x) = 0.000110001100011...

由于计算内存有限,不能存储无限循环小数,必须对小数进行四舍五入或者截断,至此,产生误差。

此时,如果我们需要更高的精度,则可以使用 decimal 模块

from decimal import Decimala = Decimal('4.2')
b = Decimal('2.1')
print(a + b)
print(a + b == Decimal('6.3'))

之所以 Decimal 对象可以精确计算,根本原因是因为其使用了不同于 IEEE 754 的表示形式来存储数值。Decimal 对象基于十进制数,而非二进制数,不直接在硬件上运行,而是以软件模拟十进制的方式进行计算。优点在于的确能够提供精确的十进制表示和计算,但是缺点很明显,区别于直接在硬件上计算,其会运行的较慢。

此外,decimal 模块还可控制计算过程中的各个方面,比如数字的位数以及四舍五入等等。其需要创建一个本地的上下文环境然后修改其设定。

from decimal import localcontext, Decimala = Decimal('1.3')
b = Decimal('1.7')
print(a / b)
with localcontext() as ctx:ctx.prec = 3print(a / b)

讨论

其实在真实世界中,极少有什么东西需要计算到小数点后17位,因此,在计算中引入微小误差不足挂齿。而且明显原生依托于硬件计算的浮点数运算性能要快上很多,如果要执行大量的计算,那性能问题就非常重要了。

这也就是说,误差就像病菌一样,无法完全忽略误差。很多时候,我们需要按照项目需求以及任务类型来做选择。

# 尤其要注意大数和小数加在一起的时候
nums = [1.23e+18, 1, -1.23e+18]
print(sum(nums))
>>> 0
# 通过使用 math.fsum() 方法解决
import math
print(math.fsum(nums))
>>> 1

综上所述,decimal 并非浮点数运算的最佳方案,或者说,没有最佳方案,选择只有最合适的吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/35162.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python编程编辑器PyCharm 界面介绍

PyCharm 界面介绍 当你打开 PyCharm 后,会看到以下主要界面区域: 1)菜单栏: 位于界面最顶端,包含文件(File)、编辑(Edit)、查看(View)、导航&a…

qemu 调试 Linux kernel 基于 x86_64

配置qemu: cd qemu/ mkdir build cd build/ $ ../configure --enable-slirp \ --enable-slirp-smbd --smbd/home/hipper/ex_ubuntu-22.4.4-live-server_qemu/smba_00 \ --target-list"riscv32-softmmu riscv64-softmmu x86_64-softmmu" make -j 创建…

ICMAN液位检测——WS003B管道检测模组

ICMAN液位检测之WS003B管道检测模组 体积小,成本低, 液位检测精度高, 有水输出低电平无水高电平, 适用于饮水机、咖啡机、扫地机器人、洗地机等, 有需要朋友快联系我吧! AWE展会不容错过的ICMAN检测模组…

[大师C语言(第四十篇)]C语言最危险行为盘点

C语言因其高效和灵活性被广泛应用于系统编程、嵌入式系统、操作系统等领域。然而,这些特性也使得C语言容易产生一些危险行为,可能导致程序错误、安全漏洞甚至系统崩溃。本文将盘点C语言中最危险的行为,并对其背后的技术进行详细解析。 第一部…

PostgreSQL 基本SQL语法(二)

1. SELECT 语句 1.1 基本 SELECT 语法 SELECT 语句用于从数据库中检索数据。基本语法如下: SELECT column1, column2, ... FROM table_name; 例如,从 users 表中检索所有列的数据: SELECT * FROM users; 1.2 使用 WHERE 条件 WHERE 子…

RabbitMQ实践——搭建多人聊天服务

大纲 用户登录创建聊天室监听Stream(聊天室)发送消息实验登录Tom侧Jerry侧 创建聊天室Jerry侧Tom侧 进入聊天室Jerry侧Tom侧 发送消息Jerry发送消息Jerry侧聊天室Tom侧聊天室 Tom发送消息Jerry侧聊天室Tom侧聊天室 代码工程参考资料 在《RabbitMQ实践——…

Webpack: 前端资深构建工具

概述 如果你是一名前端工程师,相信之前或多或少听过、用过 Webpack 这一构建工具,它能够融合多种工程化工具,将开发阶段的应用代码编译、打包成适合网络分发、客户端运行的应用产物如今,Webpack 已经深深渗入到前端工程的方方面面…

简单了解IoC

IoC 什么是IoC? IoC(Inversion of Control),即控制反转,这是一种设计思想,在Spring指将对象的控制权交给Spring容器,由容器来实现对象的创建、管理,程序员只需要从容器获取想要的对…

java设计模式(四)原型模式(Prototype Pattern)

1、模式介绍: 原型模式(Prototype Pattern)是一种创建型设计模式,它允许对象在创建新实例时通过复制现有实例而不是通过实例化新对象来完成。这样做可以避免耗费大量的资源和时间来初始化对象。原型模式涉及一个被复制的原型对象…

ES6模板字符串详解

ES6是JavaScript语言的一次重大更新,引入了许多新特性和语法改进,其中模板字符串是一个非常实用和灵活的语法特性。它可以让我们从数组或对象中提取值,并赋给对应的变量,让代码变得更加简洁和易读。 本文将深入探讨ES6解构赋值的语…

域控制器BSP开发工程师面试题

在域控制器BSP(Board Support Package)开发工程师的面试中,可能会遇到以下一些问题。以下是根据参考文章和相关知识整理的面试题及其可能的回答格式: 面试题1:请简要介绍一下您对域控制器BSP的理解。 回答: 域控制器BSP,即板卡支持包,是嵌入式系统开发中的关键组成部…

Nginx开发--动静分离和URLRewrite

05 【动静分离和URLRewrite】 1.动静分离介绍 为了提高网站的响应速度,减轻程序服务器(Tomcat,Jboss等)的负载,对于静态资源,如图片、js、css等文件,可以在反向代理服务器中进行缓存&#xff…

减少液氮罐内液氮损耗的方法

监测与管理液氮容器的密封性能 液氮容器的密封性能直接影响液氮的损耗情况。一个常见的损耗源是容器本身的密封不良或老化导致的泄漏。为了有效减少液氮损耗,首先应当定期检查液氮容器的密封性能。这可以通过简单的方法如肉眼检查外观,或者更精确的方法…

KALI LINUX 开启ssh免登录服务及固定ip及

SSH以进行远程登录 在Kali Linux中启用SSH以进行远程登录,请按照以下步骤操作: 安装SSH服务:sudo apt update sudo apt install openssh-server 已安装可忽略 sudo systemctl start ssh 启动SSH服务 sudo systemctl enable ssh 确保SSH服务设置为开机启动: (可选)如…

xxl-job 分布式任务调度 基本使用

xxl-job 是一个分布式任务调度平台,使用非常方便。 官网:https://gitee.com/xuxueli0323/xxl-job 工作原理类似于nacos 执行器注册到调度中心 调度中心分配任务 执行器执行任务 docker-compose 配置 version: 3 services:xxl-job:image: xuxueli/xxl-…

科普文:外贸垃圾邮件判定

国外垃圾邮件判定规则 很多时候,外贸的沟通多以邮件为主,他们作为专业的采购商,每天邮箱里都会塞满了邮件。因此,为了提高工作效率,很多国外客户喜欢使用垃圾邮件过滤器来过滤掉一部分垃圾邮件。 以下几种情况会触发垃…

《重构》读书笔记【第1章 重构,第一个示例,第2章 重构原则】

文章目录 第1章 重构,第一个示例1.1 重构前1.2 重构后 第2章 重构原则2.1 何谓重构2.2 两顶帽子2.3 为何重构2.4 何时重构2.5 重构和开发过程 第1章 重构,第一个示例 我这里使用的IDE是IntelliJ IDEA 1.1 重构前 plays.js export const plays {&quo…

【学习笔记】ElasticSearch

中文社区:https://elasticsearch.cn/ Cluster集群,一个ES集群由一个或多个节点(Node)组成,每个集群都有一个Cluster Name作为标识 Node节点,一个ES实例就是一个node,一个机器可以有多个实例&a…

工具提示框(Tooltip): 设计、应用与最佳实践

工具提示框(Tooltip): 设计、应用与最佳实践 引言 工具提示框(Tooltip)是用户界面(UI)设计中的一种常见元素,它为用户提供关于界面元素或操作的额外信息。当用户将鼠标悬停在某个元素上时,Tooltip会以文本形式显示相关信息,帮助用户更好地理解和使用界面。本文将探讨…

AcWing算法基础课笔记——高斯消元

高斯消元 用来求解方程组 a 11 x 1 a 12 x 2 ⋯ a 1 n x n b 1 a 21 x 1 a 22 x 2 ⋯ a 2 n x n b 2 … a n 1 x 1 a n 2 x 2 ⋯ a n n x n b n a_{11} x_1 a_{12} x_2 \dots a_{1n} x_n b_1\\ a_{21} x_1 a_{22} x_2 \dots a_{2n} x_n b_2\\ \dots \\ a…