为何<比!更快!=?

时间:2014-07-16 11:03:02

标签: c performance operators collatz

  

问题:考虑以下算法来生成序列   数字。从整数n开始。如果n是偶数,除以2.如果n是   奇数,乘以3并加1.用新值重复此过程   n,当n = 1时终止。输入将由一系列组成   成对的整数i和j,一对整数的perline。所有整数   将小于1,000,000且大于0。   对于每一对   输入整数i和j,输出i,j的顺序与它们相同   出现在输入中,然后是整数的最大循环长度   介于i和j之间。这三个数字应该分开   一个空格,所有三个数字在一行上,一行   每行输入的输出。

示例输入:

1 10

示例输出:

1 10 20

所以我写了这个:

#include <stdio.h>
#include <string.h>

struct line{int in1;int in2;int result;};

int cycle(int in);

int main(int argc, char *argv[]) {
    int cycle(int in);
    char c;
    int firstIn=0;
    struct line l[500] ;
    int pointer=0;

    while(2<3){
        l[pointer].in1=0;
        l[pointer].in2=0;
        scanf("%u %u",&l[pointer].in1,&l[pointer].in2);
        if(l[pointer].in1<1||l[pointer].in2<1){
            break;
        }

        int maxCyc=0;
        int j,m;
        int min,max;
        if(l[pointer].in1>l[pointer].in2){
            max=l[pointer].in1;
            min=l[pointer].in2;
        }
        else{
            max=l[pointer].in2;
            min=l[pointer].in1;
        }
        for(j=min;j<=max;j++){

            m = cycle(j);
            if(m>maxCyc)
                maxCyc=m;
        }
        l[pointer].result=maxCyc;
        printf("%d %d %d\n",l[pointer].in1,l[pointer].in2,l[pointer].result);
        pointer++;
    }
}

int cycle(int in){
    int cyc = 1;
    while(in>1){
        if(in%2==0){
            cyc++;
            in=in/2;
        }
        else{
            cyc++;
            in=in*3+1;
        }
    }
    return cyc;
}

它完全可以,但是当你将循环方法中的while(in>1)更改为while(in!=1)时,速度会慢得多。我的问题是为什么?!

  

while(in>1):0.683秒

的时间      

当它while(in!=1)时:我等了5分多钟   发生了:))

     

输入:1 1000000

没有无限循环或其他因为in根本不能低于1(因为它必须已经是1)。

祝你好运

2 个答案:

答案 0 :(得分:1)

正如你告诉我的那样,这是一个简单的溢出问题。

max int值为2,147,483,647;因此,当我将int cycle(int in)更改为int cycle(long long int in)时,我的问题就解决了。

我也认为我对while(in>1)的第一个回答是错误的。

当发生整数溢出时,该值将低于0.这就是while(in!=1)是一个infinte循环的原因。

我真的很累,我自己也没弄明白。抱歉:)

答案 1 :(得分:1)

当您使用输入值cycle致电113383时,该流程最终会将n设置为 827370449和3 * 827370449 + 1是2482111348,它大于最大signed int并被解释为-1812855948。所以你的第一个负数应该没有负数。

如果此过程最终将n设置为-2,则它将在-2和-1之间无限循环。可能还有其他循环我没有考虑过。

如果你使用unsigned int,有可能(我没有检查过)这最终会溢出,这不会导致负值,但会导致不正确价值,使结果无效。

无论您使用什么整数表示,在每个循环的顶部比较n(maximum-1)/3可能是个好主意,其中maximum是最大可能的正值你的整数类型,只是为了确保你没有溢出。