提问人:Aditeya 提问时间:8/9/2022 最后编辑:Peter CordesAditeya 更新时间:6/9/2023 访问量:3737
为什么 x = x * y / z 给出的结果与整数的 x *= y / z 不同?
Why does x = x * y / z give a different result from x *= y / z for integers?
问:
我有以下功能:
pub fn s_v1(n: &u64) -> u64 {
let mut x: u64 = 1;
for i in 1..=*n {
x = x * (*n + i) / i;
}
x
}
此代码给出了正确答案s_v1(&20) == 137846528820
但是,如果我将 for 循环中的行更改为x *= (*n + i) / i;
答案变为s_v1(&20) == 16094453760
为什么结果不同?不和 ?x = x * y
x *= y
答:
33赞
Chayim Friedman
8/9/2022
#1
因为 和 与左关联性具有相同的优先级,所以表达式不是*
/
x * ((*n + i) / i)
(与 相同)但x *= (*n + i) / i
(x * (*n + i)) / i
评论
3赞
Pablo H
8/10/2022
这两件事在精确算术上是相同的,所以根本原因不是(只是)优先级本身,而是整数算术。
11赞
Martin Kealey
8/10/2022
#2
正如其他人所指出的,有两个促成因素:
a*=b/c
等价于 和 not to(这是隐含的)。a=a*(b/c)
a=a*b/c
a=(a*b)/c
/
表示根据操作数的类型进行划分。在这种情况下,操作数都是整数,因此表示丢弃任何余数的整数除法,因此与 (除非是 的精确倍数)不同。/
(a*b)/c
a*(b/c)
b
c
如果要替换循环中的行,则需要拆分两个操作:
for i in 1..=*n {
x *= *n + i;
x /= i;
}
该算法的一个缺点是,当答案应该在 MAXINT/2n 和 MAXINT 之间时,它不会产生正确的结果。为此,您实际上需要利用您尝试执行的操作:
for i in 1..=*n {
if (x % i == 0) {
x /= i;
x *= *n + i;
} else if (*n % i == 0) {
x *= *n / i + 1;
} else {
x *= *n + i;
x /= i;
}
}
评论
x = x * y
是相同的,但你的表达式没有这种形式。那里有一个分裂。 与 不同。操作顺序不同x *= y
x = x * y / z
x *= y / z
/
a * (b /c)
(a * b) / c
u64
u64
*n
x = x * (*n + i) / i;
x *= (*n + i); x /= i;
nCr(2*n,n)