所以我正在阅读这个名为“学习Python第四版”的PDF教程。现在我找到了一个我不理解的部分,因为我几乎是Python的初学者。我在谈论这一部分:
现在我没有得到第一个例子的解释。它确实说:
It turns out that there are two ways to print every object: with full precision(as in the first result shown here)
但这是怎样的with full precision
?
它可能只是对文本中的python程序员很容易解释,但我似乎没有得到它。
答案 0 :(得分:13)
这不是Python问题,而是浮点数性质的问题。事实证明,计算机不能代表数字。谁知道?
如果你有时间,我建议你阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic。
现在,对于实际的Python方面,每个对象都有一个名为__str__
的方法和一个名为__repr__
的方法。这些应该产生在各种情况下显示的字符串。如果您在任何对象上使用内置repr
或str
函数,或者在字符串格式中使用"%r"
或"%s"
格式,则会看到这些内容。在交互式提示符下评估某些内容时,默认情况下会获得repr
。当您将某些内容传递给print
时,默认情况下会获得str
。
浮点数对象的__repr__
定义为以最大精度(至少可以达到十进制)表示它们,而__str__
的定义方式是{{1}}往往看起来更像你想要向用户展示的东西。用户不想知道浮点数不是实数,因此它不会向它们显示额外的精度。
答案 1 :(得分:4)
“str
和repr
之间有什么区别”甚至“完全精确意味着什么”的答案取决于Python版本。
repr(f)
的行为在3.1和 2.7 中发生了变化。
在2.7(包括Python 3.0)之前,repr(f)
最多会提供17位有效数字,就好像使用%17g
格式化一样。 IEEE-754浮点值具有53个有效二进制数字,大约为16个十进制数字。 17位有效数字保证每个二进制值产生不同的十进制值。
repr()
float
的{{1}}在很多情况下更短:它现在基于最短的十进制字符串,可以保证回到x
。与之前版本的Python一样,保证x
恢复float(repr(x))
。
在Python 3.2中改变了x
的行为:
在2.x,3.0和3.1中:str(f)
给出十进制值四舍五入到只有12位有效数字,就好像用str(f)
格式化一样;精度由Objects/floatobject.h中的%12g
宏控制。
在3.2+中,PyFloat_STR_PRECISION
表现为相同至str(f)
- 作为repr(f)
输出,因为3.1显然更加人性化,并且自从repr
正在失去精确度,它是decided that starting from Python 3.2 str(f)
should be identical to repr(f)
。
以下示例演示了str(f)
行为的变化。旧的行为是:
repr
而新行为是:
Python 2.6.8 (unknown, Jan 26 2013, 14:35:25)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 3.1415 * 2
6.2830000000000004
>>>
Python 2.7.3 (default, Mar 13 2014, 11:03:55)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 3.1415 * 2
6.283
(在Python 3.2之前)的旧行为是将值舍入为12位有效数字,丢失信息:
str
自Python 3.2以来的新行为表现得像Python 2.7.3 (default, Mar 13 2014, 11:03:55)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> str(0.1000000000000999)
'0.1'
>>> 0.1 == 0.1000000000000999
False
>>> repr(0.1000000000000999)
'0.1000000000000999'
:
repr
为什么要进行舍入的原因是因为Python中的浮点数表示为IEEE-754双精度;一个数字需要64位,其中1位保留用于符号,10位用于指数,53位用于尾数(实际数字)。
许多值(例如π或 1/3 )无法准确表示为IEEE-754二进制浮点值。即使是 0.01 这样的常见数字也无法准确表示。
Python 3 Python 3.2.3 (default, Feb 20 2013, 14:44:27)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> str(0.1000000000000999)
'0.1000000000000999'
>>> repr(0.1000000000000999)
'0.1000000000000999'
的方法float
将数字转换为十六进制表示,可用于轻松查看问题:
hex()
因此,作为十六进制,数字0.01将以二进制近似为 1.47AE147AE147A4147AE ...·2 -7 ;舍入到53个有效位中最接近的数字,表示为 1.47AE147AE147B·2 -7
在我对问题Precision of repr(f), str(f), print(f) when f is float的回答中,我已经写了一些关于>>> (0.01).hex()
'0x1.47ae147ae147bp-7'
如何在2.7,3.1中工作的更详细的细节。
答案 2 :(得分:3)
基本上,计算机的浮点计算存在舍入误差。因此,如果您执行1.*1000./1000.
,最终可能会遇到1.0000004
或类似内容。这是计算机存储在内存中的内容。但是,您可能不希望看到1.0000004作为该计算的结果。因此,当您打印结果时,计算机会进行舍入,您只需1
。但是你必须知道它不是计算机内存中的真正价值 - 它只是对你的实际浮点数的一种舒适的可视化。
答案 3 :(得分:2)
完全精确,它们表示数字存储为的所有小数位数。由于数字如何存储在计算机上(二进制),这通常不是100%准确。
答案 4 :(得分:2)
你正在读的书是不精确的。如果您真的希望看到浮点数达到完全精度,请使用decimal
模块:
>>> import decimal
>>> decimal.Decimal(3.1415 * 2)
Decimal('6.28300000000000036237679523765109479427337646484375')
每个(有限的)二进制浮点数可以精确地表示为(有限的)十进制浮点数。反之亦然 - 实际上,大多数十进制浮点数不能完全表示为(有限)二进制浮点数。
旧版CPython的不同之处在于repr(a_float)
产生了17位有效小数。虽然证明这很困难,但事实证明,17个有效十进制数字足以使eval(repr(a_float)) == a_float
对于实现为IEEE-754“双精度”二进制浮点(几乎所有机器现在都使用)的浮点数始终为真 - 和16有效十进制数字是不够的。 17是不“全精度”,它“足够的精度使得往返总是有效”。
在当前版本的CPython中,repr(a_float)
生成最短的十进制字符串,使eval(repr(a_float)) == a_float
。要做到这一点要困难得多。对于“随机”浮动,它可能仍然会生成17个十进制数字,但对于“简单浮动”,人们倾向于手动输入,它可能会生成您键入的相同字符串。
答案 5 :(得分:1)
这可能是一个相当令人困惑的问题!数学3.1415 * 2 = 6.283
,但在浮点运算中,由于四舍五入而引入了小错误。大多数显示此类计算结果的系统会自动对此进行校正,并为您提供所期望的结果。在python中,当你print
一个数字时会发生这种情况。另一方面,repr
显示它的原样,包括微小的错误。通常错误是如此之小以至于不值得担心,但如果您在高精度环境中工作,那么您可能更喜欢decimal
模块来避免错误。
答案 6 :(得分:0)
python类应该定义两种特殊方法:__repr__
和__str__
。
当您想要对象本身的“精确”表示时,会调用第一个。这意味着如果您复制/粘贴__repr__
的输出,您将获得完全相同的对象。然而,这种表示并不总是人类可读的(特别是在处理更复杂的对象时),因此存在__str__
。它的功能是给出对象价值的文本表示,这是人类友好的。