Why does the floating-point value of 4*0.1 look nice in Python 3 but 3*0.1 doesn't?

前端 未结 4 1476
心在旅途
心在旅途 2020-11-30 18:38

I know that most decimals don\'t have an exact floating point representation (Is floating point math broken?).

But I don\'t see why 4*0.1 is printed nic

4条回答
  •  执念已碎
    2020-11-30 19:16

    repr (and str in Python 3) will put out as many digits as required to make the value unambiguous. In this case the result of the multiplication 3*0.1 isn't the closest value to 0.3 (0x1.3333333333333p-2 in hex), it's actually one LSB higher (0x1.3333333333334p-2) so it needs more digits to distinguish it from 0.3.

    On the other hand, the multiplication 4*0.1 does get the closest value to 0.4 (0x1.999999999999ap-2 in hex), so it doesn't need any additional digits.

    You can verify this quite easily:

    >>> 3*0.1 == 0.3
    False
    >>> 4*0.1 == 0.4
    True
    

    I used hex notation above because it's nice and compact and shows the bit difference between the two values. You can do this yourself using e.g. (3*0.1).hex(). If you'd rather see them in all their decimal glory, here you go:

    >>> Decimal(3*0.1)
    Decimal('0.3000000000000000444089209850062616169452667236328125')
    >>> Decimal(0.3)
    Decimal('0.299999999999999988897769753748434595763683319091796875')
    >>> Decimal(4*0.1)
    Decimal('0.40000000000000002220446049250313080847263336181640625')
    >>> Decimal(0.4)
    Decimal('0.40000000000000002220446049250313080847263336181640625')
    

提交回复
热议问题