首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >fractions.Fraction()返回不同的no.denom。解析浮点数或其字符串表示时对

fractions.Fraction()返回不同的no.denom。解析浮点数或其字符串表示时对
EN

Stack Overflow用户
提问于 2018-02-09 13:34:11
回答 2查看 692关注 0票数 9

我知道浮点数学的本质,但我仍然感到惊讶的是:

代码语言:javascript
复制
from fractions import Fraction

print(Fraction(0.2))       # -> 3602879701896397/18014398509481984
print(Fraction(str(0.2)))  # -> 1/5

print(Fraction(0.2)==Fraction(str(0.2)))  # returns False
print(0.2 == float(str(0.2)))             # but this returns True!

文档上我找不到任何可以解释这一点的东西。它确实指出:

...In加法,任何表示有限值并被浮点构造函数接受的字符串也被分数构造函数接受.

但对我来说,这意味着类似于float()的行为,我只是没有看到如上面所示。

对此有什么解释吗?

需要注意的是,上面显示的行为并不是特定于值(0.2),而是一般的行为;我尝试过的一切都是这样的。

有趣的是:

代码语言:javascript
复制
from fractions import Fraction


for x in range(1, 257):
    if Fraction(str(1/x))==Fraction(1/x):
        print(x)

只打印小于所选上限的2幂:

代码语言:javascript
复制
1
2
4
8
16
32
64
128
256
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-09 13:59:39

如果给出一个字符串,请查看fractions.py中的fractions.py实现:

regex _RATIONAL_FORMAT (如果您对解析部分感兴趣,请参见链接)将numerator表示为0decimal表示为2

fractions.py源开始引用,并附上我的评论

代码语言:javascript
复制
elif isinstance(numerator, str):
    # Handle construction from strings.
    m = _RATIONAL_FORMAT.match(numerator)
    if m is None:
        raise ValueError('Invalid literal for Fraction: %r' %
                         numerator)
    numerator = int(m.group('num') or '0')       # 0
    denom = m.group('denom')                     
    if denom:                                    # not true for your case
        denominator = int(denom)
    else:                                        # we are here
        denominator = 1
        decimal = m.group('decimal')             # yep: 2
        if decimal:
            scale = 10**len(decimal)             # thats 10^1
            numerator = numerator * scale + int(decimal)    # thats 0 * 10^1+0 = 10
            denominator *= scale                 # thats 1*2
        exp = m.group('exp')  
        if exp:                                  # false
            exp = int(exp)
            if exp >= 0:
                numerator *= 10**exp
            else:
                denominator *= 10**-exp
    if m.group('sign') == '-':                   # false
        numerator = -numerator

else:
    raise TypeError("argument should be a string "
                    "or a Rational instance")

出处报价

因此,'0.2'被精确地解析为2 / 10 = 0.2,而不是我的计算器在0,20000000000000001110223024625157上发布的最近的浮点近似。

经典:它们不仅仅是使用float( yourstring ),而是解析和计算字符串本身,这就是两者不同的原因。

如果使用相同的构造函数并提供floatdecimal,则构造函数使用内置as_integer_ratio()获取分子和分母作为该数字的表示。

浮点表示最接近0.2的值是0,2000000000000000001110223024625157,这正是as_integer_ratio()方法返回命名子和分母的结果。

正如艾瑞克马克·狄金森所指出的,这个浮点值被它的二进制表示限制为“接近0.2”。当被放入str()时,将被截断为精确的'0.2' -因此在

代码语言:javascript
复制
print(Fraction(0.2))       # -> 3602879701896397/18014398509481984
print(Fraction(str(0.2)))  # -> 1/5
票数 6
EN

Stack Overflow用户

发布于 2018-02-09 14:41:16

print(Fraction(0.2))中,源文本0.2被转换为浮点值.此转换的结果正好是0.200000000000000011102230246251565404236316680908203125,或3602879701896397/18014398509481984。然后将这个值传递给Fraction,后者生成相同的值,表示为一个有理数。

print(Fraction(str(0.2)))中,0.2再次转换为浮点值,从而得到上面的数字.然后str将其转换为字符串。在当前的Python版本中,当浮点值转换为字符串时,Python通常不会产生精确的数学值。相反,它会产生刚好足够的数字,以便将字符串转换为浮点,从而产生输入数字。在这种情况下,结果是“0.2”。所以字符串“0.2”被传递给Fraction。然后Fraction分析“0.2”并确定为1/5。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48707089

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档