what should be the output

J

junky_fellow

Guys,

What should the statement below print on a 32 bit system.

printf("%x\n", (((long)1 - (unsigned long)3)) >>1);

which is the correct output:
0xffffffff or 0x7fffffff ?

thanks for any help...
 
J

jameskuyper

This is not sufficiently precise. A 32-bit system could have 32-bit
ints and 64-bit longs. I assume he meant that 'long' is 32 bit.
Well, neither, since you didn't tell printf to use the 0x.
True.

But to address your real question, there is no "correct" output. For
one thing, you apply the >> operator to a signed, negative value --

The types "long" and "unsigned long" have the same conversion rank.
6.3.1.8p1: "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."

Therefore, the subtraction is carried out as an unsigned long
substraction. As a result, there's no problem with the shift.
which is implementation defined. Then you pass a long where printf
expects an int, which is undefined.

True.
 
P

Peter Nilsson

Trent said:
Well, neither, since you didn't tell printf to use the 0x.

As you point out later, the length modifier l is also needed.
But to address your real question, there is no "correct"
output.

With %lx it's the same as...

printf("%lx", (ULONG_MAX-1)/2);
 For one thing, you apply the >> operator to a signed,
negative value --

No, the long will be promoted to unsigned long via the
usual arithmetic conversions.
 
P

Peter Nilsson

Anthony Fremont said:
If UINT_MAX is greater than LONG_MAX, the final result of
the subtract should be unsigned after the integral promotion.

There is no integral promotion involved in the expressions
given since every integer and operand already has a rank of
int or higher.
 
J

jameskuyper

Anthony said:
If UINT_MAX is greater than LONG_MAX, the final result of the subtract
should be unsigned after the integral promotion. ...

The result of the subtraction is unsigned, regardless of whether or
not UINT_MAX > LONG_MAX.
... So after right shifting
that, the vacated bits should be filled with 0 giving you 0x7fffffff. Else,
the result of the subtract would be signed. It would still be
implementation defined as to whether the vacated bit positions would be
filled with 0 or 1.

When a negative value is shifted to the right, it isn't just the
vacated bits whose value is implementation-defined:

6.5.7p5: "... If E1 has a signed type and a negative value, the
resulting value is implementation-defined."

The entire resulting value (all 32-bits, in this case) is
implementation-defined.
 
J

jameskuyper

Eric said:
One correction: There's no undefined behavior in this use
of the shift operator. The subtraction finds operands of mixed
types, long and unsigned long, and to arrive at a common type
it first promotes the long to unsigned long. After the
promotion, the expression looks like `1UL - 3UL', and the
result is `ULONG_MAX - 2UL'. ...

Actually, ULONG_MAX - 1UL. The rule is that you add (or subtract) the
mathematical value of ULONG_MAX+1 as many times as are needed to get a
value in the range [0,ULONG_MAX].

... ULONG_MAX is implementation-
defined, but on "a 32 bit system" we'll assume it's 0xffffffffUL,
so the result of the subtraction is 0xfffffffdUL. Observe that
the type of this result is unsigned long, not signed long.
Right-shifting an unsigned long introduces high-order zero
bits, so after the shift the result is 0x7ffffffUL.

If the result of the subtraction had been 0xffffffdUL, then the result
after the shift would have been 0x7ffffffeUL.
 
V

vippstar

As you point out later, the length modifier l is also needed.


With %lx it's the same as...

printf("%lx", (ULONG_MAX-1)/2);

Which is, AFAIK, the same with
printf("%lx", ULONG_MAX / 2);

Or am I missing something?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,432
Messages
2,571,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top