Why does my test of sign always report “negative”?

空扰寡人 提交于 2019-12-25 08:24:15

问题


The following program should print whether the sum of the elements of the array is positive or negative:

#include <stdio.h>

#define ARR_SIZE 5

int main()
{
   int array[ARR_SIZE] = {1,-2,3,4,-5};
   unsigned sum;
   int i;

   for(i=0, sum=0; i < ARR_SIZE; i++)
   {
         sum += array[i];
         printf("sum %d\n ", sum);
   }


         printf("%d\n",sum);
   if(sum>-1) printf("non negative\n");
   else printf("negative\n");
   return 0;
 }

The program doesn't do what it is supposed to; it prints 'negative' no matter what array values it receives.

For example, the sum of the array written in the above program is 1, and therefore I expected the following output:

sum 1
sum -1
sum 2
sum 6
sum 1
1
non negative

While the output is:

sum 1
sum -1
sum 2
sum 6
sum 1
1
negative

Why do I get this output?


回答1:


In the expression sum > -1, the usual arithmetic conversions ("balancing") applies. Since one operand is unsigned int and the other is int, the operand -1 which is int gets implicitly converted to unsigned int. The comparison operation is carried out on type unsigned int.

In addition, unsigned variables can never hold a negative value in the first place, so the expression didn't make any sense even without the implicit conversion.




回答2:


Implicit Typecasting: When you define a variable as Unsigned and compare it with a negative number then that negative number is implicitly typecast. As we know negative numbers are stored in two's compliment, so -1 actually becomes a very big positive number. Now whatever the big number you supply it will always be less than that big number, that's why you are getting negative as answer all the time.

Possible solution: use ternary operator to handle + and - numbers. Thanks




回答3:


the output because of your declaration of sum variable, you declared it as a unsigned sum just change the unsigned sum to signed sum or int sum




回答4:


With a reasonable set of warnings enabled, a good compiler will highlight the problem:

gcc -std=c11 -fPIC -g -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds      42362568.c    -o 42362568
42362568.c: In function ‘main’:
42362568.c:19:10: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    if(sum>-1) printf("non negative\n");
          ^

It's always good advice to enable as many warnings as you can; for historical reasons, most compilers give very few warnings unless you remember to ask for them.

Note that if you change the comparison to if (sum >= 0), then you'll get a different (and perhaps more useful) message, because the literal 0 can be treated as 0u:

42362568.c:19:10: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
    if(sum>=0) printf("non negative\n");
          ^~



回答5:


When we trying to compare two different (same data type) sign's of variables ,The compiler implicitly(internally ) will treat both variables as higher signed type(unsigned type).

Hear if(sum > -1) is your code.You are trying to compare unsigned sum , signed constant so compiler internally convert -1 as unsigned . If we consider integer size as 2 bytes then sum = 1(as your code) but the -1 will be converted to unsigned value 65535 (do 2's compliment for -1) now your code will be simplified to if(sum > 65535), so the condition isFALSE that's why only always you are getting un- expected result.If you want to avoid this problem, always compare same signed type variables(if both variables are same data type , other wise there is no problem with different signed types also).




回答6:


two's compliment of 1 ( assume int size is 2 Bytes )

0000 0000 0000 0001 (1 binary value)

1111 1111 1111 1110 (one's compliment)

1111 1111 1111 1111 (two's compliment)(this value is 65535)

this value is replacing with -1 in your code.



来源:https://stackoverflow.com/questions/42362568/why-does-my-test-of-sign-always-report-negative

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!