C++和Python中的/的区别
使用 Python 2.7
我在尝试解决 LeetCodeOJ 上的逆波兰表达式问题。
我用 Python 写了一个简单的解决方案,如下所示:
class Solution:
# @param tokens, a list of string
# @return an integer
def evalRPN(self, tokens):
stack = []
for token in tokens:
if token in ["+" , "-" ,"*", "/"]:
op1 = stack.pop()
op2 = stack.pop()
if token == "+":
stack.append(op2+op1)
elif token == "-":
stack.append(op2-op1)
elif token == "*":
stack.append(op2*op1)
elif token == "/":
stack.append(op2/op1)
else:
stack.append(int(token))
if len(stack) == 1:
return stack.pop()
else:
return 0
但是在一个测试用例上被拒绝了:
Input: ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]
Output: 12
Expected: 22
不过,如果我把 '/'
操作改成 stack.append(int(op2 / (op1*1.0)))
,就成功了。
在这个输入下,/
操作只执行了一次,计算 6/-132
,无论用哪种方法,结果都是 -1
。
奇怪的是,尽管这两种计算方式的结果都是 -1
,但整个程序的输出却不同。如上所示,第一种方法的结果是 12
,而第二种方法的结果是 22
。是什么原因导致的呢?
我访问了这个 链接,但它只提到 Python 和 C++ 中的 /
运算符有一些区别。那到底有什么区别呢?
3 个回答
在C++中,如果你把两个整数相除,结果也是一个整数,而且会向零取整。比如说,
1 / 2 = 0
-1 / 2 = 0
但是如果其中至少有一个数是浮点数(也就是带小数的数),那么结果就会是浮点数。
在Python 2中,如果你用整数相除,/这个符号会进行整数除法,结果会向下取整,比如说
1 / 2 = 0
-1 / 2 = -1
而在Python 3中,他们改变了/的用法,现在它总是进行浮点数除法。
1 / 2 = 0.5
如果你想在Python 3中进行整数除法,可以使用//这个符号。
1 // 2 = 0
-1 // 2 = -1
Python和C++之间的主要区别只有两个。
首先,对于负数,Python是向负无穷方向取整,而C++是向0取整。所以,-10 / 3
在Python中结果是-4,而在C++中通常是-3。
其次,在Python 3.x版本中,或者在Python 2.x中使用from __future__ import division
时,用/
除两个整数会得到一个float
类型的结果,因此9 / 3
在Python 3.x中是3.0,而在C++或Python 2.x中是3。
那么,如果你想在Python中实现C++那样的除法,该怎么办呢?其实,int
函数总是向0取整,而不是向负无穷取整。所以,如果你强制进行浮点数除法,然后对结果使用int
,而不是让它直接进行整数除法,你就会得到和C++一样的结果。这就是你链接的代码中使用int(b/(a*1.0))
的原因。我不确定这是不是最好的写法(尤其是没有注释解释目的),但这就是它的用处。
同时,如果你真的想看看为什么会有这些不同,可以尝试在调试器中运行你的代码,或者使用在线可视化工具,或者在每一步的评估循环中添加print
语句。这样你就能清楚地看到在哪一步出现了问题——参数是什么,输出是什么,以及你期望的输出是什么。然后你可以把问题简化成一个更简单的情况,比如:
a = 4
b = -13
print(b/a)
print(int(b/(a*1.0)))
接下来,为了弄清楚这些不同的原因,可以把int(b/(a*1.0))
分解成几个步骤:
print(a*1.0)
print(b/(a*1.0))
print(int(b/(a*1.0)))
如果你在用Python 2的话,/
这个符号会进行整数除法,也就是说,它会把余数去掉,只给你一个向下取整的结果。只有当至少有一个参与运算的数是float
类型(浮点数)而不是int
类型(整数)时,才会得到浮点数的结果。你可以通过把其中一个数乘以1.0
来解决这个问题,或者也可以用float(...)
把其中一个数转换成浮点数。这和C++有点像,不过在C++中,结果是向零取整,这意味着如果有一个负数参与运算,结果会不同:
C++:
1 / 2 // gives 0
(-1) / 2 // also gives 0
Python 2:
1 / 2 # gives 0
(-1) / 2 # gives -1 (-0.5 rounded down)
Python 3:
在Python 3中,/
总是进行正确的浮点数除法,这意味着你总是会得到一个float
类型的结果。如果你想恢复之前的行为,可以使用//
。
1 / 2 # gives 0.5
(-1) / 2 # gives -0.5
1 // 2 # gives 0
(-1) // 2 # gives -1
补充说明:
因为你在用Python 2.7(见编辑后的问题),所以你确实遇到了整数除法的问题。想要在Python 2中获得Python 3那种新的行为,你可以在你的程序开头运行
from __future__ import division
(这必须放在最开始的位置,否则解释器会报错)
关于int(something)
的另一个补充
要注意的是,虽然整数除法是向下取整,但转换为整数时是向零取整,这和C++中的整数除法一样。