Python中的错误数学计算?

78

我刚开始学习Python,所以这可能是我的错误,但是......

我正在尝试使用Python。我喜欢将其用作计算器,并且正在逐步完成一些教程。

今天我遇到了奇怪的事情。我想找出2013 * 2013,但我写错了,写成了2013 * 013,结果得到了这个:

>>> 2013*013
22143

我用计算器检查了一下,22143是错误的答案!2013 * 13应该是26169。

为什么Python会给我一个错误的答案?我的老卡西欧计算器不会有这种情况...


2
相关:https://dev59.com/aGcs5IYBdhLWcg3wPxnN - mgilson
6
+1 是给你注意到了的。我知道它是一个八进制数,但如果我不知道,我现在会认为 2013*13 是 22143。你是如何发现这是错误答案的? - 11684
11
我曾经在高中时进行过心算,我认为22143似乎比应有的要小一些。所以我使用了我的可靠计算器进行了核对。 - James Elegan
2
相信你那聪明的脑袋,加一分。 - Sean Allred
13
如果两个数字的个位数都是3,它们的乘积的个位数一定是9。这属于小学数学内容。 - Aleksandar
显示剩余5条评论
4个回答

137

由于八进制算术,013实际上是整数11。

>>> 013
11

如果在数字前加上前导零,013 将被解释为一个八进制数,1*81 + 3*80 = 11。

注意:这种行为在 Python 3 中已经发生了 改变。以下是来自PEP 3127 的一句特别恰当的引用:

默认的整数八进制表示对于不熟悉 C 类语言的人来说很容易造成混淆。因为对于 Python 语言本身而言,'013' 的意思是 '十进制11' 而不是 '十进制13',所以非常容易无意中创建带有错误值的整数对象,这与大多数人赋予此字面值的含义不同。


14
或许这就是为什么Python 3将0123语法视为非法,而总是要求使用0o123的原因之一。 - Tim Pietzcker
3
是的,以 0 前缀后跟 0-8 的数字表示的是八进制。以 0x 前缀后跟 0-9a-f 的数字表示的是十六进制。 - Joe Frambach
97
程序员为什么总是把万圣节和圣诞节搞混?因为DEC25 == OCT31!Nyuk nyuk nyuk. (注:这句话是一个笑话,其中的“DEC25”表示十进制数25,而“OCT31”表示八进制数31。在计算机编程中,使用八进制时以数字0开头,因此八进制数31实际上等于十进制数25。) - Joe Frambach
16
@JoeFrambach,0前缀后跟0-7是八进制数 :) - Mark Tolonen
5
仁慈的独裁者第一次没有正确地从Lisp复制。这些东西必须清晰明了:#xFF,#o777,#b1011。 - Kaz
显示剩余8条评论

36

013 是一个八进制整数字面量(等同于十进制整数字面量 11),因为它具有前导的 0。

>>> 2013*013
22143
>>> 2013*11
22143
>>> 2013*13
26169

在我熟悉的大多数语言中,八进制整数字面量通常以0开头,十六进制整数字面量通常以0x开头。由于您经历的确切混淆,Python 3会引发SyntaxError错误:

>>> 2013*013
  File "<stdin>", line 1
    2013*013
           ^
SyntaxError: invalid token

而需要使用0o0O代替:

>>> 2013*0o13
22143
>>> 2013*0O13
22143 

谢谢你的回答!我觉得这个八进制有点令人困惑,但至少现在我知道了 :) - James Elegan
3
非常感谢您。如我和@wim的回答所述,Python社区正在尽力减少Python 3中八进制字面量对新手的困惑。但是,了解这一点非常重要--您可以确定您将在Python 2.X或其他语言中再次遇到0前缀的八进制字面量。 - Darshan Rivka Whittle
2
PEP 3127在这方面是一个略带幽默的阅读材料...例如“新的Python用户(目前)可能对他们的数字不正常的延迟发现感到困惑,我们可以通过立即向他解释Python不喜欢前导零(并带有合理的信息!),或者我们可以将这个教学经验委托给Internet Explorer浏览器中的JavaScript解释器,并让他尝试在那里调试问题。” - wim

7

5
这主要是对@Wim的回答进行了一些扩展,Python使用特定的前缀来指示整数字面量的基数。如果没有前缀,整数将被解释为十进制。带有“0x”的整数将被解释为十六进制整数。完整的语法规范在这里,但如果您不熟悉形式化语法,则有点难以理解: http://docs.python.org/2/reference/lexical_analysis.html#integers 该表格基本上表示,如果您想要一个长值(即超出普通int容量的值),请写数字后跟字母“L”或“l”; 如果您希望数字以十进制解释,请正常编写数字(没有前导0); 如果您希望它以八进制解释,请在前面加上“0”,“0o”或“0O”; 如果您想要它以十六进制解释,请在前面加上“0x”; 如果您想要它以二进制解释,请在前面加上“0b”或“0B”。

Python 2.7 不算太老了,对吧?所以我永远不需要添加 L。(我一直听到 Python 3 的好处,也许我应该安装并使用它?) - James Elegan
@JamesElegan 我找不到任何确切的信息,说明哪个之前的版本需要为字面量添加后缀,以便容纳比 int 更大的值(我可能错了,也许没有这样的版本)- 我自己的记忆可以回溯到 2.4,我相当确定它不需要。但是,如果您不依赖尚未移植的任何库,Python 3通常是值得转换的。 - lvc
Python 2.7是Python 2的最新版本;事实上,2.7.4就在上周末发布了。Python 3与Python 2有很大的不同,但最终大多数Python代码将来都会以Python 3代码编写,或者至少这似乎是目标。因此,如果你刚开始学习并可以选择哪个版本学习,我建议你学习3或同时学习2和3。 - Kyle Strand
Python开发者在这里有一个关于选择哪个版本的解释:http://wiki.python.org/moin/Python2orPython3 - Kyle Strand
嘿,好的。从今天得到的所有反馈来看,我想我会尝试Python 3。也许我会有更少的惊喜 :) - James Elegan
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接