鱼C论坛

 找回密码
 立即注册
查看: 379|回复: 6

[已解决]第八课的习题:为什么用了Decimal,算出来的结果还是不对

[复制链接]
发表于 2025-6-4 11:22:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
代码如下:
import decimal
a=decimal.Decimal(0.1)
b=decimal.Decimal(0.3)
c=a+a+a-b
print(c)
结果c的结果是一个很奇葩的数字,为什么用了decimal还是不对?
最佳答案
2025-6-4 11:23:24
在Python中使用`decimal`模块时,**初始化方式**是关键问题!你的代码用浮点数初始化`Decimal`对象,但浮点数本身就有精度误差。正确做法是用**字符串**初始化,避免浮点误差传递:


  1. import decimal
  2. a = decimal.Decimal('0.1')  # 用字符串初始化!
  3. b = decimal.Decimal('0.3')  # 用字符串初始化!
  4. c = a + a + a - b
  5. print(c)  # 输出 0.0
复制代码


错误原因分析:
1. decimal.Decimal(0.1) 中的 0.1 是浮点数,实际内存值为近似值 0.100000000000000005551115...
2. 这个近似值被直接传递给`Decimal`,导致后续计算继承误差

正确做法总结:
  • 永远用字符串初始化小数:Decimal('0.1')
  • 需要整数时可直接传数字:Decimal(10)
  • 涉及金钱等精确计算时,建议全局设置精度:

    1.   decimal.getcontext().prec = 6  # 设置6位有效数字
    2.   
    复制代码



试试修改后的代码,结果将是精确的 0.0!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2025-6-4 11:23:24 | 显示全部楼层    本楼为最佳答案   
在Python中使用`decimal`模块时,**初始化方式**是关键问题!你的代码用浮点数初始化`Decimal`对象,但浮点数本身就有精度误差。正确做法是用**字符串**初始化,避免浮点误差传递:


  1. import decimal
  2. a = decimal.Decimal('0.1')  # 用字符串初始化!
  3. b = decimal.Decimal('0.3')  # 用字符串初始化!
  4. c = a + a + a - b
  5. print(c)  # 输出 0.0
复制代码


错误原因分析:
1. decimal.Decimal(0.1) 中的 0.1 是浮点数,实际内存值为近似值 0.100000000000000005551115...
2. 这个近似值被直接传递给`Decimal`,导致后续计算继承误差

正确做法总结:
  • 永远用字符串初始化小数:Decimal('0.1')
  • 需要整数时可直接传数字:Decimal(10)
  • 涉及金钱等精确计算时,建议全局设置精度:

    1.   decimal.getcontext().prec = 6  # 设置6位有效数字
    2.   
    复制代码



试试修改后的代码,结果将是精确的 0.0!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-6-4 20:48:46 | 显示全部楼层
0.1&0.3别用小数用字符串
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-6-4 20:49:19 | 显示全部楼层
这个可以参考我之前做的计算器好熟悉的问题
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-6-4 20:53:38 | 显示全部楼层
可以去看看小甲鱼写的文档
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 22:30 | 显示全部楼层
Decimal里面用小数的字符串形式
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 19:28 | 显示全部楼层
本帖最后由 jackz007 于 2025-6-11 22:15 编辑

            我们通常使用的是 64 位浮点数,一个 64 位数的表达空间是 2 ^ 64,也就是 18446744073709551616,就是说,一个 64 位的数最多只能表达出 18446744073709551616 个不同的数值,就浮点数而言,这 18446744073709551616 个不同的数中,一半需要用来表达正值,另一半需要用来表达负值,很显然,用这点空间表达浮点数根本就不可能够用,比如,你能告诉我,在 0.000001 - 0.000002 之间究竟有多少个不同的浮点数?答案是无数个。
            我们现在面临的问题是,如何用有限个数值来表达无限数量的浮点数?
            你一定使用过尺子,用有限个刻度可以测量出任意长度,同样的道理,在计算机内部,使用带有 18446744073709551616 个刻度的尺子也同样可以衡量出浮点数的数值,实际上可以理解为,用 18446744073709551616 个固定的数值来刻度所有的浮点数,实际上就是使用一个距离最近的刻度点来表达一个具体的浮点数。总结成一句话就是,计算机不可能精确表达每一个浮点数。所以,常常可以看到,为一个变量赋值一个浮点数,但是,原样打印出来的变量值却会有所变化,就是这个道理。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-12 17:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表