This question already has answers here:
Comparison operation on unsigned and signed integers
(7 answers)
Closed 7 years ago.
#include<stdio.h>
int main(){
unsigned int a = 6;
int b = -20;
( a+b > 6 ) ? puts( "a") : puts( "b");// if a+b > 6 then a else b
}
I presumed that the output should be "b" but it wasn't.
output: a
C99 standard, section 6.3.1.8
if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.
So here b(value= -20) is converted to unsigned type (a large value), it will be equivalent to -
( a+(unsigned int)b > 6 )
Therefore , output is a not b
The type of the expression a + b is unsigned int, which is the result of arithmetic conversions that are applied whenever the arithmetic operators are used on operands of different types. Each operand is first converted to this common type, and the result of converting -20 to an unsigned int is a very large value.
Related
This question already has answers here:
Implicit type promotion rules
(4 answers)
Type conversion - unsigned to signed int/char
(5 answers)
Closed 4 years ago.
void foo(void) {
unsigned int a = 6;
int b = -20;
if (a+b > a) {
printf("> a");
} else {
printf("< a");
}
}
I am trying to understand what is going on with the integer promotion example above. I know that for a = 6 and b = -20 the output should be > a due to b being promoted to unsigned int. However, the output goes to < a if I assign b = -5. Shouldn't the output be the same in this case as well since the value b = -5 is also promoted to an unsigned int?
The reason for this has to do with the method in which the signed value is converted to unsigned.
Section 6.3.1.3 of the C standard regarding conversions of signed and unsigned integers dictates how this occurs:
2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that
can be represented in the new type until the value is in the range of
the new type.60)
...
60) The rules describe arithmetic on the mathematical value, not the value of a given type of expression.
In your example with b equal to -20, when it is converted to unsigned UINT_MAX + 1 is added to the value, so the converted value is UINT_MAX - 19. When you then add the value of a (6), you get UINT_MAX - 13. This value is larger than a, so "> a" is printed.
If you set b equal to -5, the converted value is UINT_MAX - 4. Adding 6 to this gives you UINT_MAX + 2. Since math on unsigned int values occurs modulo UINT_MAX + 1, the actual result is 1. This is less than 6, so "< a" is printed.
Also, what is happening here is not integer promotion but integer conversion. Promotion happens first if any integer type in an expression has a rank less than int. That is not the case here.
This question already has answers here:
My computer thinks that signed int is smaller then -1? [duplicate]
(3 answers)
sizeof() operator in if-statement
(5 answers)
Closed 5 years ago.
Why does it print 2 when the value of SIZE is greater than -1?
Link to the code: http://ideone.com/VCdrKy
#include <stdio.h>
int array[] = {1,2,3,4,5,6,7,8};
#define SIZE (sizeof(array)/sizeof(int))
int main(void) {
if(-1<=SIZE) printf("1");
else printf("2");
return 0;
}
Both arguments are in different type
Argument are 'converted' to 'common' type, and 'common' between signed -1 and unsigned SIZE is unsigned.
So -1 is converted -> 0xfffffff (depends on architecture) that is grater than SIZE
From the C standard on integer conversions:
If the operand that has unsigned integer type has rank greater than
or equal to the rank of the type of the other operand, the operand
with signed integer type is converted to the type of the operand with
unsigned integer type.
Here -1 is of type int, and SIZE is of type size_t. On your c compiler, size_t is unsigned and has greater than or equal rank to int, so the -1 is converted to size_t, which gives a large positive number (SIZE_MAX)
This question already has answers here:
Comparison operation on unsigned and signed integers
(7 answers)
Closed 5 years ago.
Here a + b is -14 which should have been lesser than 'a' and hence should have printed NO but it printed yes.
unsigned int a = 6;
int b = -20;
if((a+b) > a){
printf("Yes");
} else {
printf("NO");
}
return 1;
According to the C Standard (6.3.1.8 Usual arithmetic conversions)
1 Many operators that expect operands of arithmetic type cause
conversions and yield result types in a similar way. The purpose is to
determine a common real type for the operands and result. For the
specified operands, each operand is converted, without change of type
domain, to a type whose corresponding real type is the common real
type. Unless explicitly stated otherwise, the common real type is also
the corresponding real type of the result, whose type domain is the
type domain of the operands if they are the same, and complex
otherwise. This pattern is called the usual arithmetic conversions:
...
Otherwise, if the operand that has unsigned integer type has rank
greater or equal to the rank of the type of the other operand, then
the operand with signed integer type is converted to the type of the
operand with unsigned integer type.
Types unsigned int and int have the same rank.
Thus the value of the variable b from your example is interpreted as an unsigned value.
If to use the correct conversion specifier %u for the expression ( a + b ) in a function call of printf then you might get
#include <stdio.h>
int main(void)
{
unsigned int a = 6;
int b = -20;
printf( "a + b = %u\n", a + b );
return 0;
}
a + b = 4294967282
You compare signed with unsigned. As all values of unsigned cannot be accommodated in the signed so the the signed value is converted to unsigned and is much larger than 6
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
A riddle (in C)
Can someone please explain what is wrong with this code?
#include<stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int d;
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
printf("%d\n",array[d+1]);
return 0;
}
d <= (TOTAL_ELEMENTS-2)
d is signed: it is an int.
But TOTAL_ELEMENTS is unsigned: sizeof yields a size_t value and size_t is an unsigned type.
In the <= expression d is converted to an unsigned number by the way of the usual arithmetic conversions and it becomes a huge number.
When d is -1 and is compared with TOTAL_ELEMENTS-2 (which is size_t type, ie an unsigned integer), d is promoted to a large number in an unsigned type. Then, d is greater than TOTAL_ELEMENTS-2, so the loop is never executed.
c11
§ 6.5.8 Relational operators
If both of the operands have arithmetic type, the usual arithmetic conversions are
performed.
§ 6.3.1.8 Usual arithmetic conversions
Otherwise, if the operand that has unsigned integer type has rank greater or
equal to the rank of the type of the other operand, then the operand with
signed integer type is converted to the type of the operand with unsigned
integer type.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
A riddle (in C)
see this code
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int d;
for(d=-1;d <= TOTAL_ELEMENTS-2;d++)
printf("%d\n",array[d+1]);
return 0;
}
now this loop won't run.
sizeof() would return an unsigned value so TOTAL_ELEMENTS has an unsigned value.
now , coming to the for loop, please tell me if the unary operator '-' works on signed int 2 or an implicit conversion takes place into unsigned and then the '-' operator works.
In your example d is converted to an unsigned int in the comparison. But -1 cannot be represented as an unsigned int value, so it is is converted to UINT_ MAX. To avoid this behaviour you can convert the right side of the comparison to an signed int by prepending (int).
See Understand integer conversion rules for details on integer conversion in C.
There's no unary operator in d <= TOTAL_ELEMENTS-2.
The TOTAL_ELEMENTS-2 reduces to an expression with a binary operator of -. This expression then becomes unsigned because one of its operands is unsigned.
In the case of d <= TOTAL_ELEMENTS-2, d's type is also converted to unsigned int for the same reason.
The relevant portion of the standard is section 6.3.1.8#1 (ISO/IEC 9899:1999) which says:
"Otherwise, if the operand that has unsigned integer type has rank greater or
equal to the rank of the type of the other operand, then the operand with
signed integer type is converted to the type of the operand with unsigned
integer type."
Yes, d also has an unsigned type in that expression, because of promotion, which is why the loop fails.
However, the question is whether the C compiler "thinks":
(unsigned) ((unsigned) 5 - (unsigned) 2)
i.e. promoting 2 to unsigned, or:
(unsigned) ((unsigned) 5 - (signed) 2)
i.e. subtraction taking operands of both types. Of course, it doesn't matter, as it would be the same operation for both. However, the whole point is that subtracting will return a value of one type, so theoretically it can only take arguments of that type. So it's the first (unsigned int 2).
P.S. (-2) is unary, while (5 - 2) is binary.
I suspect the unsigned type of sizeof() to propagate to the expression TOTAL_ELEMENTS-2 and then to both operands of d <= TOTAL_ELEMENTS-2. Inserting (int) juste before TOTAL_ELEMENTS fixes the issue.
look , that '-' operator being unary was a stupid thing.forget it.it was the binary '-' , i realise.
when 2 is converted to unsigned int it becomes unsigned 2 , so TOTAL_ELEMENTS-2 has a value equal to unsigned 5 , and then when d is being converted to an unsigned int it gets a large positive value and
so the loop fails.
is that happening here??
and yes, i didn't write this code,this is some c puzzle i found on the web.
thank ya all.