Kar*_*elm 63 python operator-precedence
我正在研究如何在没有math模块的情况下进行地板/天花板操作。我通过使用楼层除法解决了这个问题//,并发现负数“给出了上限”。所以这有效:
>>> 3//2
1
>>> -3//2
-2
Run Code Online (Sandbox Code Playgroud)
我希望答案是肯定的,所以首先我尝试了--3//2,但这给出了 1。我推断这是因为 Python 的计算结果--为+。所以为了解决这个问题,我发现我可以使用-(-3//2)),问题就解决了。
但我找到了另一个解决方案,即(我包含了前面的示例进行比较):
>>> --3//2 # Does not give ceiling
1
>>> 0--3//2 # Does give ceiling
2
Run Code Online (Sandbox Code Playgroud)
我无法解释为什么包含 0 有帮助。我已阅读有关除法的文档,但没有找到任何帮助。我认为这可能是因为评估顺序:
如果我使用--3//2作为示例,从我所拥有的文档中,该示例Positive, negative, bitwise NOT在该示例中是最严格的,并且我猜其计算结果--为+. 接下来是Multiplication, division, remainder,所以我猜这就是+3//2评估结果1,我们就完成了。我无法从文档中推断出为什么包含0应该改变结果。
参考:
Mis*_*agi 85
Python 使用该符号-作为一元( -x) 和二元( x-y) 运算符。它们具有不同的运算符优先级。
具体来说,排序方式//是:
-//-通过引入0as 0--3//2,第一个-是二进制文件 -并且最后应用。如果没有前导0as --3//2,两者-都是一元并且一起应用。
相应的评估/语法树大致是这样的,首先评估底部的节点以在父节点中使用它们:
---------------- ----------------
| --3//2 | 0--3//2 |
|================|================|
| | ------- |
| | | 0 - z | |
| | -----+- |
| | | |
| -------- | ----+--- |
| | x // y | | | x // y | |
| -+----+- | -+----+- |
| | | | | | |
| ----+ +-- | ---+ +-- |
| | --3 | | 2 | | | -3 | | 2 | |
| ----- --- | ---- --- |
---------------- ----------------
Run Code Online (Sandbox Code Playgroud)
因为一元运算-一起应用,所以它们抵消了。相反,一元和二元分别在除法之前和之后-应用。
Kar*_*tel 30
这是一个简单的操作顺序问题。
--3//2是相同的(-(-3)) // 2。由于左侧没有任何内容,因此每个都-必须是一元否定;并且这比//;具有更高的优先级 so3被求反两次(得到 3),然后除以 2。
0--3//2是相同的0 - ((-3) // 2)。既然左边有东西,那么第一个-一定是二进制减法,它的优先级比低//。第二个-仍然是一元否定;-3除以2yield -2,然后从 中减去该值0。
Ter*_*edy 18
了解 CPython 实际如何计算的另一种方法是使用 dis 模块来查看它对其堆栈机器的实际执行情况。
>>> import dis
>>> dis.dis('0--3//2')
1 0 LOAD_CONST 0 (2)
2 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
哎呀,常量是在编译期间计算的,所以使用一个名称。
>>> t=3
>>> dis.dis('0--t//2')
1 0 LOAD_CONST 0 (0)
2 LOAD_NAME 0 (t)
4 UNARY_NEGATIVE
6 LOAD_CONST 1 (2)
8 BINARY_FLOOR_DIVIDE
10 BINARY_SUBTRACT
12 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)