【问题标题】:Different outputs for same algorithm in different languages不同语言中相同算法的不同输出
【发布时间】:2011-04-29 16:44:33
【问题描述】:

Java 源代码:

package n1_problem;

/**
 *
 * @author nAwS
 */
public class loop {

    int loop(long i)
    {
        long n=i;
        int count=1;
        while(n>1){
            if(n%2==0){
                n=n/2;
            }
            else{
                n=3*n+1;
            }
            count++;
        }
       return count; 
    }

    int max_cycle(long j,long k){

        int max=-1;
        for(long i=j;i<=k;i++){
            int count=loop(i);
            if(count>max){
                max=count;
            }
        }
        return max;
    }


}


public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        loop lp=new loop();
        System.out.println("Max Cycle:"+lp.max_cycle(1,1000000));
    }

}

C源代码:

int main()
{
    long r,h;
    int f=0;
    do 
    {
        printf("Value,r:");
        scanf("%ld",&r);
        printf("Value,h:");
        scanf("%ld",&h);

        f=max_cycle(r,h);
        printf("Max:%d\n",f);

    }while(getch()!='e');
}

int loop(long i)
{
        long n=i;
        int count=1;
        while(n>1)
        {
            if(n%2==0){
                n=n/2;
            }
            else{
                n=3*n+1;
            }
            count++;
        }
       return count; 
    }

    int max_cycle(long j,long k)
    {

        int max=1;
        long i=0;
        for(i=j;i<=k;i++){

            int count=loop(i);
            if(count>max){
                max=count;
            }
        }
        return max;
    }

对于 3n+1 问题算法,这两个代码之间没有逻辑上的区别。唯一的问题是在 C 中它给出 476 作为最大循环数,而在 java 中它是 525...为什么??

【问题讨论】:

  • 我怀疑您的代码通过签名溢出调用了未定义的行为。

标签: java c algorithm


【解决方案1】:

在大多数 C 编译器中,long 通常定义为 4 字节整数(long int 的缩写)。在 Java 中,long 被定义为一个 8 字节的整数。

您可以更改您的 Java 代码以使用 int 来获取 4 字节整数,或者在您的 c 程序中使用 long long 来获取 8 字节整数(我认为这是在 C99 中添加的,它可能会也可能不会在您的编译器上可用)。

【讨论】:

  • 是的,从技术上讲范围是指定的,但是以任何其他方式实现它确实没有多大意义。
  • 在 C 中,longs 不是“一般”的 4 字节。它们至少 32 位,通常是 32 或 64(例如在 x86_64-linux-gnu 上)。无论如何,如果您关心获得正确大小的整数,则不要猜测要添加的神奇正确的 longs 数量,而是使用 stdint.h 或等效的 C99 之前的标头。
【解决方案2】:

Java 定义了整数类型的大小和表示,C 没有。在 Java 中,long 是 64 位 2 的补码。在 C 中,它至少是 32 位,也许更多,并且可以是有符号的、无符号的、1 的补码、2 的补码、符号和幅度,或其他。

你有没有注意到,如果你改变了这行 Java 代码

long n = i;

到这里

int n = (int)i;

您得到的结果与您的 C 代码相同吗?可能您使用的是 2 的补码机器,而您的 C 编译器决定 longs 是 32 位。

【讨论】:

  • 终于!..我明白了!...使用 unsigned long 它给出了正确的结果...:)
【解决方案3】:

Java 代码中,在方法@​​987654322@ 中,ma​​x 被初始化为-1,在C 代码中它是1强>。只需检查一下,这是否会导致逻辑错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 2014-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-26
    相关资源
    最近更新 更多