好的。我有这样的欧几里德分部: a = b * q + r
我知道要获得r,我可以做模数:a % b
但是如何获得q? //
似乎不起作用。
答案 0 :(得分:3)
如果a和b是整数,只需使用整数除法/
。
答案 1 :(得分:2)
If a = 7 and b = 3, then q = 2 and r = 1, since 7 = 3 × 2 + 1.
If a = 7 and b = −3, then q = −2 and r = 1, since 7 = −3 × (−2) + 1.
If a = −7 and b = 3, then q = −3 and r = 2, since −7 = 3 × (−3) + 2.
If a = −7 and b = −3, then q = 3 and r = 2, since −7 = −3 × 3 + 2.
可能有更简单的解决方案。
int Ediv(int a, int b) {
printf("a:%2d / b:%2d = ", a,b);
int r = a % b;
if (r < 0) r += abs(b);
printf("r:%2d ", r);
return (a - r) / b;
}
void Etest() {
printf("q:%2d\n", Ediv(7,3));
printf("q:%2d\n", Ediv(7,-3));
printf("q:%2d\n", Ediv(-7,3));
printf("q:%2d\n", Ediv(-7,-3));
}
a: 7 / b: 3 = r: 1 q: 2
a: 7 / b:-3 = r: 1 q:-2
a:-7 / b: 3 = r: 2 q:-3
a:-7 / b:-3 = r: 2 q: 3
OP断言“我知道要获得r
,我可以做模数:a % b
”。当a
为否定时,此操作失败。
此外,%
是“余数运算符”。在C中,当a
为负时,欧几里德余数和模数之间的差异发生。 Remainder calculation for the modulo operation
答案 2 :(得分:1)
chux 的答案很好,因为它是正确理解问题的答案(与接受的答案不同)。 Daan Leijen 的 Division and Modulus for Computer Scientists 也提供了一个有证明的算法:
/* Euclidean quotient */
long quoE(long numer, long denom) {
/* The C99 and C++11 languages define both of these as truncating. */
long q = numer / denom;
long r = numer % denom;
if (r < 0) {
if (denom > 0)
q = q - 1; // r = r + denom;
else {
q = q + 1; // r = r - denom;
}
return q;
}
这个算法与chux的算法是等价的。它看起来有点冗长,但在 x86 上它可能需要少一条 div
指令,因为该指令执行“divmod”——同时返回 q 和 r。
答案 3 :(得分:0)
举个例子:
7 = 3*2 + 1
2(q
)可以通过7/3
获得,即a/b = q
。