Python中带符号乘法与地板除法不满足交换律?原因及编码规则
问题原因与解决方案
为什么两个表达式结果不同?
这是Python的运算优先级结合性和整数地板除特性共同作用的结果:
先看第一个表达式:
-1 * abs(-123)//10
Python中乘法(*)和除法(//)属于同一优先级,运算时从左到右依次执行:- 第一步:计算
-1 * abs(-123)→-1 * 123 = -123 - 第二步:计算
-123 // 10→ Python的//是地板除(向下取整),-123÷10=-12.3,向下取整后得到-13
- 第一步:计算
再看第二个表达式:
abs(-123)//10 * -1
同样按从左到右的顺序执行:- 第一步:计算
abs(-123)//10→123//10 = 12 - 第二步:计算
12 * -1 = -12
- 第一步:计算
关键差异点在于:负数的地板除结果和直观的“截断小数”不同,当运算顺序改变时,负数是否参与除法运算直接影响了最终结果。
编码时如何保证结果一致可预测?
- 用括号强制指定运算顺序:不管默认优先级如何,用括号明确标记需要先执行的运算,比如把你需要的逻辑用括号包裹,比如想要先算乘法再除法就写
(-1 * abs(-123))//10,想要先算除法再乘法就写(abs(-123)//10) * -1,完全消除歧义。 - 明确地板除的特性:记住Python的
//是向下取整,不是截断小数,尤其是处理负数时,不要想当然按正数除法的逻辑推导。 - 拆分复杂表达式:把多步运算拆成单独的变量赋值,比如:
这样不仅可读性更高,也能避免因运算顺序导致的错误。num = abs(-123) product = -1 * num result = product // 10
内容的提问来源于stack exchange,提问作者kaytu
相关产品推荐
相关产品推荐

