python - 分数背后的重要原因(0.1) = 3602879701896397/36028797018963968

标签 python floating-point fractions

我正在查看Python documentation of fractions 并尝试这段代码:

from fractions import Fraction

>>> print("Fraction (0.5):", Fraction(0.5))
Fraction (0.5): 1/2
>>> print("Fraction (0.1):", Fraction(0.1)) 
Fraction (0.1): 3602879701896397/36028797018963968
>>> print(1/10) 
0.1

查看 Fraction(0.1)结果我以为是我的电脑问题,但是当我在几台电脑上尝试时,结果都是一样的。

我的问题

  1. 是否有任何计算原因来选择这些奇数 3602879701896397/36028797018963968而不是1/10就像 1/2因为它选择了 Fraction(0.5) .
  2. Python 中存在更多这样的内容吗?

最佳答案

是的,那是因为这是 float 0.1 的整数比(无法用 float 精确表示):

>>> (0.1).as_integer_ratio()
(3602879701896397, 36028797018963968)

>>> '{:.30f}'.format(0.1)   # just to show that it can't be represented exactly I print 30 digits of 0.1
'0.100000000000000005551115123126'

如果您想要正确的分数,您需要使用两个参数或传入一个字符串:

>>> Fraction(1, 10)
Fraction(1, 10)

>>> Fraction('0.1')
Fraction(1, 10)

或者limit the denominator从 float 创建它之后(不保证在所有情况下都能工作):

>>> Fraction(0.1).limit_denominator()
Fraction(1, 10)

至于你的第二个问题:数学中有无限多个有理数(可以精确地表示为分数的十进制数),但计算机使用 64 位来表示 double (Python float 类型)。这意味着只有少数实数可以精确表示为double。所以还有很多其他号码也有同样的问题,仅举几例:

>>> Fraction(0.2)
Fraction(3602879701896397, 18014398509481984)

>>> Fraction(0.3)
Fraction(5404319552844595, 18014398509481984)

>>> Fraction(1/3)
Fraction(6004799503160661, 18014398509481984)

关于python - 分数背后的重要原因(0.1) = 3602879701896397/36028797018963968,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45920732/

相关文章:

python - 如何在 Python 中将带分数的字符串转换为 float

java - 如何获取数字小数部分的长度?

python - 使用 Python 和正则表达式从一组分隔符中第一次出现拆分字符串

python - 如何快速禁用 python 中的 try 语句进行测试?

c++ - Z3 - 浮点运算 API 函数 Z3_mk_fpa_to_ubv

c - 为什么C语言中的cexp(+infinity+I*infinity)=+/-infinity+I*NaN?

c# - 在 C# 中将 double 转换为分数作为字符串

python - Matplotlib 日期作为刻度

python - R/Python/Julia 中 Matlab 的类型转换函数的等价物是什么

java - 对 REST Assured 浮点比较的混淆