为何整数运算中x = x * y / z与x *= y / z结果不同?
为什么Rust中
x = x * y / z与x *= y / z结果不同? 先看你的两段核心代码逻辑:
- 正确版本:
x = x * (*n + i) / i; - 错误版本:
x *= (*n + i) / i;
两者完全不等价,问题出在运算顺序和整数除法的截断特性上:
1. 运算顺序差异
- 正确写法的执行顺序是:先计算
x * (*n + i),再将结果除以i。 - 错误写法的执行顺序是:先计算
(*n + i) / i(整数除法,直接截断小数部分),再将结果乘以x。
2. 整数除法的截断问题
你的函数本质是计算组合数C(2n, n)(比如n=20时是C(40,20)=137846528820),这个计算过程中,每一步的x * (*n + i)必然能被i整除(组合数的数学性质),所以正确写法里的除法是精确的,不会丢失精度。
但错误写法中,(*n + i)/i并不总是整数:比如当n=20、i=3时,20+3=23,23/3在Rust整数除法中结果是7(截断了小数部分0.666...),而正确写法中是先算x*23(此时x是231),得到5313,再除以3得到1771——这是精确的整数结果。错误写法里用231*7=1617,直接和正确值差了154,后续循环的误差会不断累积,最终导致结果完全错误。
总结
- 原写法利用组合数的数学性质,通过「先乘后除」避免了整数除法的截断误差,保证每一步计算都是精确的。
- 修改后的「先除后乘」提前引入了截断误差,破坏了计算的精确性,最终得到错误结果。
内容的提问来源于stack exchange,提问作者Aditeya
相关产品推荐
相关产品推荐

