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?
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 compareunsigned sum , signed constant
so compiler internally convert-1 as unsigned
. If we consider integer size as 2 bytes thensum = 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 toif(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).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
With a reasonable set of warnings enabled, a good compiler will highlight the problem:
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 literal0
can be treated as0u
:the output because of your declaration of
sum
variable, you declared it as aunsigned sum
just change theunsigned sum
tosigned sum
orint sum
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.In the expression
sum > -1
, the usual arithmetic conversions ("balancing") applies. Since one operand isunsigned int
and the other isint
, the operand-1
which isint
gets implicitly converted tounsigned int
. The comparison operation is carried out on typeunsigned 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.