如何在C中获得欧几里德分裂的元素(没有余数)

时间:2014-02-03 17:52:04

标签: c

好的。我有这样的欧几里德分部: a = b * q + r

我知道要获得r,我可以做模数:a % b

但是如何获得q? //似乎不起作用。

4 个答案:

答案 0 :(得分:3)

如果a和b是整数,只需使用整数除法/

答案 1 :(得分:2)

使用Euclidean division

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