数字打印为负值,但不知何故测试为正值

时间:2014-04-18 05:05:38

标签: c printf

这也许是我遇到的最奇怪的事情:一个同时是正面和负面的数字! (我可以向你证明,因为我有输出/输入here at ideaone的代码链接。基本上,我的输出是负数,但更奇怪的是:当我检查它是否小于零,它是假的(?!)。更奇怪的是:当你将它乘以一个以外的数字时,它会切换回打印为正数。

当我在Xcode上编译时,这个错误不会发生,但是在互联网(或其他编译器)上编译时会发生这种错误,例如链接中的那个。

准确理解它的作用并不重要,我想知道为什么这个值同时是负面的和正面的。

#include <stdio.h>
#include <cmath>

int main()
{
    unsigned long answer,T,n,N,a,d,b,L1,amount;

    scanf("%ld",&T); // number of test cases to loop through
    while (T--) {
        scanf("%ld",&N); 

        amount = 0;
        answer = 0;
        n=N-N%2;
        for (a = 1; a <= n/2; a++) {
            d = N-a;
            L1 = a*d;          

            for (b = 1; b*b < L1 ; b++) {
                // "amount" is always a positive number
                amount = 2*(((L1-1)/b) - b + 1) - 1;

                if (d==a) answer+=amount;
                else answer+=2*amount;  // we are only adding positive values to this
            }
        }

        if (answer<0) printf("This answer is less than zero %ld\n",answer);
        if (answer>0) printf("This answer is greater than zero %ld\n",answer);
        printf("%ld\n",answer);
        printf("%ld\n",2*answer/2);
    }
}

输入:

1 2500

输出:

Success  time: 0.02 memory: 3300 signal:0
This answer is greater than zero -1842629629
-1842629629
304854019

如您所见,我的否定答案大于零。更不用说,它与我在Xcode中编译时的答案不同,即使是正面形式。

我很惊讶。它打印出一个“正面”的负数

Proof is here at ideaone.com

3 个答案:

答案 0 :(得分:5)

answer是无符号长的。 %ld在格式字符串中签名很长。将%ld更改为%lu,您不会在打印时将未签名的值更改为已签名的值,并且可以正确打印。

    if (answer<0) printf("This answer is less than zero %lu\n",answer);
    if (answer>0) printf("This answer is greater than zero %lu\n",answer);

答案 1 :(得分:1)

问题在于签署您的数据类型。你使用的是'unsigned long',技术上不能是负面的。仍然可以为其分配负数,并且仍然可以执行导致负数(例如0-1)的数学运算。但处理器总是将这些值视为正值。

我知道有些编译器会根据编译和链接时间标记对待无符号数字,这可能是造成两个编译器之间差异的原因。或者甚至可能是您使用我的网站解释代码,出于安全原因。

无论哪种方式,将声明更改为'long'并解决问题。

答案 2 :(得分:0)

我无法添加评论,但我在Ubuntu中执行,并且它与您显示相同。 仅供参考,当我输入a和25时,它没问题

myqiqiang@ubuntu:~$ ./test
1
2500
This answer is greater than zero -1842629629
-1842629629
304854019
myqiqiang@ubuntu:~$ ./test
1 25
This answer is greater than zero 12722
12722
12722