python 浮点数

发布于 2024-09-04 10:31:44 字数 186 浏览 3 评论 0原文

我有点困惑为什么 python 在这种情况下添加一些额外的十进制数,请帮忙解释一下

>>> mylist = ["list item 1", 2, 3.14]
>>> print mylist ['list item 1', 2, 3.1400000000000001]

i am kind of confused why python add some additional decimal number in this case, please help to explain

>>> mylist = ["list item 1", 2, 3.14]
>>> print mylist ['list item 1', 2, 3.1400000000000001]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

就像说晚安 2024-09-11 10:31:44

浮点数是一个近似值,它们不能精确地存储十进制数。因为它们试图仅用 64 位表示非常大范围的数字,所以它们必须在某种程度上进行近似。

意识到这一点非常重要,因为它会导致一些奇怪的副作用。例如,您可能非常合理地认为十手 0.1 的总和将为 1.0。虽然这看起来合乎逻辑,但对于浮点来说也是错误的:

>>> f = 0.0
>>> for _ in range (10):
...  f += 0.1
...
>>> print f == 1.0
False
>>> f
0.99999999999999989
>>> str(f)
1.0

您可能会认为 n / m * m == n。浮点世界再次不同意:

>>> (1.0 / 103.0) * 103.0
0.99999999999999989

或者也许同样奇怪的是,人们可能会认为对于所有 nn + 1 != n。在浮点领域,数字不能像这样工作:

>>> 10.0**200
9.9999999999999997e+199
>>> 10.0**200 == 10.0**200 + 1
True
# How much do we have to add to 10.0**200 before its 
# floating point representation changes?
>>> 10.0**200 == 10.0**200 + 10.0**183
True
>>> 10.0**200 == 10.0**200 + 10.0**184
False

请参阅 每个计算机科学家都应该了解浮点数,以获得对问题的精彩总结。

如果您需要精确的十进制表示,请查看 decimal 模块,它是 python 标准的一部分从 2.4 开始的库。它允许您指定有效数字的数量。缺点是,它比浮点慢得多,因为浮点运算是在硬件中实现的,而小数运算纯粹是在软件中进行的。它也有其自身的不精确问题,但如果您需要十进制数字的精确表示(例如对于金融应用程序),它是理想的选择。

例如:

>>> 3.14
3.1400000000000001
>>> import decimal
>>> decimal.Decimal('3.14')
>>> print decimal.Decimal('3.14')
3.14
# change the precision:
>>> decimal.getcontext().prec = 6
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.142857')
>>> decimal.getcontext().prec = 28
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.1428571428571428571428571429')

Floating point numbers are an approximation, they cannot store decimal numbers exactly. Because they try to represent a very large range of numbers in only 64 bits, they must approximate to some extent.

It is very important to be aware of this, because it results in some weird side-effects. For example, you might very reasonably think that the sum of ten lots of 0.1 would be 1.0. While this seems logical, it is also wrong when it comes to floating point:

>>> f = 0.0
>>> for _ in range (10):
...  f += 0.1
...
>>> print f == 1.0
False
>>> f
0.99999999999999989
>>> str(f)
1.0

You might think that n / m * m == n. Once again, floating-point world disagrees:

>>> (1.0 / 103.0) * 103.0
0.99999999999999989

Or perhaps just as strangely, one might think that for all n, n + 1 != n. In floating point land, numbers just don't work like this:

>>> 10.0**200
9.9999999999999997e+199
>>> 10.0**200 == 10.0**200 + 1
True
# How much do we have to add to 10.0**200 before its 
# floating point representation changes?
>>> 10.0**200 == 10.0**200 + 10.0**183
True
>>> 10.0**200 == 10.0**200 + 10.0**184
False

See What every computer scientist should know about floating point numbers for an excellent summary of the issues.

If you need exact decimal representation, check out the decimal module, part of the python standard library since 2.4. It allows you to specify the number of significant figures. The downside is, it is much slower than floating point, because floating point operations are implemented in hardware whereas decimal operations happen purely in software. It also has its own imprecision issues, but if you need exact representation of decimal numbers (e.g. for a financial application) it's ideal.

For example:

>>> 3.14
3.1400000000000001
>>> import decimal
>>> decimal.Decimal('3.14')
>>> print decimal.Decimal('3.14')
3.14
# change the precision:
>>> decimal.getcontext().prec = 6
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.142857')
>>> decimal.getcontext().prec = 28
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.1428571428571428571428571429')
分分钟 2024-09-11 10:31:44

值得注意的是,Python 3.1 有一个新的浮点输出例程,它以预期的方式对其进行舍入(它也已向后移植到 Python 2.7):

Python 3.1 (r31:73572, Aug 15 2009, 17:12:41) 
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [3.14]
>>> print(a)
[3.14]

来自 Python 3.1 中的新增功能 文档:

Python 现在使用 David Gay 的算法来查找不改变其值的最短浮点表示形式。这应该有助于减轻围绕二进制浮点数的一些混乱。

使用像 1.1 这样的数字很容易看出其重要性,该数字在二进制浮点数中没有精确的等价物。由于没有完全等价的表达式,像 float('1.1') 这样的表达式会计算为最接近的可表示值,即十六进制的 0x1.199999999999ap+01.100000000000000088817841970012523233890533447265625 以十进制表示。最接近的值过去和现在仍然用于后续浮点计算。

It is worthwhile to note that Python 3.1 has a new floating point output routine that rounds this in the expected manner (it has also been backported to Python 2.7):

Python 3.1 (r31:73572, Aug 15 2009, 17:12:41) 
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [3.14]
>>> print(a)
[3.14]

From the What's New in Python 3.1 document:

Python now uses David Gay’s algorithm for finding the shortest floating point representation that doesn’t change its value. This should help mitigate some of the confusion surrounding binary floating point numbers.

The significance is easily seen with a number like 1.1 which does not have an exact equivalent in binary floating point. Since there is no exact equivalent, an expression like float('1.1') evaluates to the nearest representable value which is 0x1.199999999999ap+0 in hex or 1.100000000000000088817841970012523233890533447265625 in decimal. That nearest value was and still is used in subsequent floating point calculations.

时光与爱终年不遇 2024-09-11 10:31:44

如前所述,浮点数是一个近似值。

如果您想要精确性,可以使用小数(这是精确的表示):
http://docs.python.org/library/decimal.html

a = [1.5, 1.49999]
a
[1.5, 1.4999899999999999]

from decimal import Decimal
b = [1.5, Decimal('1.4999')]
b
[1.5, Decimal('1.4999')]

As mentioned before, it's all about floating points being an approximation.

If you want exactness you can use a decimal (which is a precise representation):
http://docs.python.org/library/decimal.html

a = [1.5, 1.49999]
a
[1.5, 1.4999899999999999]

from decimal import Decimal
b = [1.5, Decimal('1.4999')]
b
[1.5, Decimal('1.4999')]
遗弃M 2024-09-11 10:31:44

我们可以通过以下命令修复它:

>>> x = 1.2 - 1.0
>>> x
0.19999999999999996
>>> y = float(str(x))
>>> y
0.2

我添加来自@mark的答案

We can fix it by this command:

>>> x = 1.2 - 1.0
>>> x
0.19999999999999996
>>> y = float(str(x))
>>> y
0.2

I add an answer from @mark

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文