【问题标题】:If condition on modulo, failing logical condition?如果条件为模,逻辑条件失败?
【发布时间】:2014-02-04 09:18:24
【问题描述】:

我想检查分数 2 4(例如)是否可以简化为 1 2!!
但是逻辑条件失败。

#include <stdio.h>
int main()
{
  int a,b,live=1;
  printf("\n\nInput integers for fraction:");
  scanf(" %d%d",&a,&b);
  while(live){  
        if(!(a%2 && b%2)){
            a/=2;
            b/=2;
        }else if(!(a%3 && b%3)){
            a/=3;
            b/=3;
        }else if(!(a%5 && b%5)){
            a/=5;
            b/=5;
        }else if(!(a%7 && b%7)){
            a/=7;
            b/=7;
        }else live--;

   }
   printf("Simplified Fraction is %d/%d",a,b);
} 

【问题讨论】:

  • 也许你想要a%2==0...
  • 可以while ((a%2 == 0) &amp;&amp; (b%2 == 0)) { a/=2; b/=2; } while ((a%3 == 0) &amp;&amp; (b%3 == 0)) { a/=3; b/=3; } ...。现在所有的函数调用都设置好了。

标签: c algorithm if-statement modulo fractions


【解决方案1】:

条件a%2等价于a%2 != 0,即测试a是否能被2整除。从De Morgan's Laws开始,条件if(!(a%2 &amp;&amp; b%2))等价于@987654327 @ 或if((a%2 == 0) || (b%2 == 0)),这不是你想要的。

你真的想测试if((a%2 == 0) &amp;&amp; (b%2 == 0))——也就是说,如果 both 都可以被 2 整除,而不是 either 是否可以被 2 整除。这样写是也少了很多混乱。

而且很明显,为了简化任何分数,您需要测试所有可能的素因数,这对于有限数量的if 语句是不可能的。这样做的推荐方法是使用Euclidean algorithm 确定分子和分母的最大公约数,然后将两者除以 GCD 以获得简化形式的分数。

【讨论】:

  • @nick 当然其他if()s 需要相同的更新。 }else if((a%3== 0) &amp;&amp; (b%3 == 0)){
【解决方案2】:

即使a%2b%2 中只有一个成立,(!(a%2 &amp;&amp; b%2)) 也会产生 true。

看看下面的例子:

3/4 -> a%2 == 0, b%2 == 1 -> (a%2 && b%2) == 0 -> (!(a%2 && b%2)) = = 1

您正在寻找(a%2 == 0 &amp;&amp; b%2 == 0) 而不是您的条件,对于其他条件也是如此。

【讨论】:

  • @nick 你用空格分隔你的数字吗?
【解决方案3】:

“接受答案后”的答案。

这并没有像@Adam Rosenfield 那样很好地详细说明 OP 代码的问题,但确实解决了更大的 OP 愿望“我想检查分数 2 4(例如)是否可以简化为 1 2!!”以一般的方式。

使用欧几里得算法找到最大公分母,然后将a,b 除以它。无需生成素数列表。非常快。

// Euclidean Algorithm
unsigned gcd(unsigned a, unsigned b) {
  while (b != 0) {
    int t = b;
    b = a % b;
    a = t;
  }
  return a;
}

#include <stdio.h>
int main() {
  int a, b;
  for (;;) {
    printf("\nInput positive fraction like 12/30: ");
    if (scanf("%u/%u", &a, &b) != 2)
      break;
    unsigned g = gcd(a, b);
    a /= g;
    b /= g;
    printf("Simplified Fraction is %u/%u", a, b);
  }
  return 0;
}

【讨论】:

    【解决方案4】:

    除了其他人确定的逻辑或问题之外,您的while 条件还存在无限循环。您不需要(或不想)循环使用当前代码。试试这个

    #include <stdio.h>
    int main ()
    {
      int a, b;
      printf ("\n\nInput integers for fraction:");
      scanf (" %d%d", &a, &b);
      while (a % 2 == 0 && b % 2 == 0)
        {
          a /= 2;
          b /= 2;
        }
      while (a % 3 == 0 && b % 3 == 0)
        {
          a /= 3;
          b /= 3;
        }
      while (a % 5 == 0 && b % 5 == 0)
        {
          a /= 5;
          b /= 5;
        }
      while (a % 7 == 0 && b % 7 == 0)
        {
          a /= 7;
          b /= 7;
        }
    
      printf ("Simplified Fraction is %d/%d", a, b);
    }
    

    给定输入的输出

    Input integers for fraction:2 4
    Simplified Fraction is 1/2
    
    Input integers for fraction:8 24
    Simplified Fraction is 1/3
    

    【讨论】:

    • || 而不是&amp;&amp;?如果输入 12 24 会怎样?
    • 你需要检查一下,目前它会给你 2 4。
    • “你不需要(或不想)循环”看起来是错误的方法。循环是为了接受 4 8 并最终达到 1 2。
    • @niCk 更改它以支持您的其他测试用例,我还测试了 8/24 简化为 1/3。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-14
    • 1970-01-01
    • 2011-07-26
    • 2015-02-27
    相关资源
    最近更新 更多