Many Happy Returns

  • Thread starter Richard Heathfield
  • Start date
R

Richard Heathfield

#include <stdio.h>

int main(void)
{
printf("Happy Birthday, Dennis Ritchie. %d today.\n", ~0&0x1f<<1);
return 0;
}
 
M

Martin Dickopp

Richard Heathfield said:
#include <stdio.h>

int main(void)
{
printf("Happy Birthday, Dennis Ritchie. %d today.\n", ~0&0x1f<<1);
return 0;
}

Doesn't this program cause undefined behavior?

Martin
 
P

pete

Martin said:
Doesn't this program cause undefined behavior?

#include <stdio.h>

int main(void)
{
printf("Happy Birthday, Dennis Ritchie. %u today.\n", ~0u&0x1f<<1);
return 0;
}
 
M

Mantorok Redgormor

Richard Heathfield said:
#include <stdio.h>

int main(void)
{
printf("Happy Birthday, Dennis Ritchie. %d today.\n", ~0&0x1f<<1);
return 0;
}

I can see why ~0 would be -1 since ~ inverts all bits, so your signed
bit ends up representing a negative and your value bits represent 1.
But why does 0x1f equal to some -1.994942 number? I was thinking 0x1f
would be equal to 1.000000 for %f and for %d just 1, but it doesn't.
Why is this?
 
P

pete

Mantorok said:
I can see why ~0 would be -1 since ~ inverts all bits, so your signed
bit ends up representing a negative and your value bits represent 1.
But why does 0x1f equal to some -1.994942 number? I was thinking 0x1f
would be equal to 1.000000 for %f and for %d just 1, but it doesn't.
Why is this?

0x1f is 31
0x1f << 1 is 62
 
R

Richard Heathfield

Martin said:
Doesn't this program cause undefined behavior?

What took you so long? :)

A birthday wouldn't be the same without a tiny flame atop each candle.
 
M

Mantorok Redgormor

pete said:
0x1f is 31
0x1f << 1 is 62

Duh. I was looking at 0x1f as the 'f' being a suffix. In the case of
representing numbers in base16, do these suffixes apply? Or are they
only applied to base10 numbers?

And ~0 what does the underlying representation look like for that?
I'm looking at it as

before:
00000000 00000000 00000000 00000000
^- sign bit - rest are value bits?

after:
11111111 11111111 11111111 11111111
^- sign bit now on, and so are all value bits?

Now all the bits have been inverted how do you get -1 from ~0?
 
J

Joona I Palaste

Duh. I was looking at 0x1f as the 'f' being a suffix. In the case of
representing numbers in base16, do these suffixes apply? Or are they
only applied to base10 numbers?

They only apply to base10 (ten) numbers. Not mathematically elegant,
but easier to implement.
And ~0 what does the underlying representation look like for that?
I'm looking at it as
before:
00000000 00000000 00000000 00000000
^- sign bit - rest are value bits?
after:
11111111 11111111 11111111 11111111
^- sign bit now on, and so are all value bits?
Now all the bits have been inverted how do you get -1 from ~0?

Two's complement arithmetic.

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"I said 'play as you've never played before', not 'play as IF you've never
played before'!"
- Andy Capp
 
P

pete

Joona I Palaste wrote:

The suffixes which make sense, can be applied:

printf("%lu\n", 0x1flu);
printf("%lx\n", 0x1flu);

but 0x1f is a positive integer value,
you're not going to put "float" suffix on that.
 
P

Pieter Droogendijk

On 9 Sep 2003 23:58:29 -0700
Duh. I was looking at 0x1f as the 'f' being a suffix. In the case of
representing numbers in base16, do these suffixes apply? Or are they
only applied to base10 numbers?

And ~0 what does the underlying representation look like for that?
I'm looking at it as

before:
00000000 00000000 00000000 00000000
^- sign bit - rest are value bits?

after:
11111111 11111111 11111111 11111111
^- sign bit now on, and so are all value bits?

Now all the bits have been inverted how do you get -1 from ~0?

You're thinking of one's complement. In fact what's used is two's complement:

-x = 0-x = ~x+1

if x=0, 0-0 = 0 = ~0+1

so if ~0+1 = 0, ~0 must be -1.

exercise for you: what's 4-~-4? And 8-~-~-8?
 
M

Martin Dickopp

Richard Heathfield said:
What took you so long? :)

A birthday wouldn't be the same without a tiny flame atop each candle.

c.l.c is not a good place to look for flames. Most people here are too
nice for that. Try a "religious war" newsgroup - anything with the term
"advocacy" is probably a good starting point. :)

Martin
 
D

Dan Pop

In said:
Doesn't this program cause undefined behavior?

On a one's complement implementation, it's either undefined behaviour or
claiming that someone called Dennis Ritchie has just been born :)

Dan
 
J

Joe Wright

Dan said:
On a one's complement implementation, it's either undefined behaviour or
claiming that someone called Dennis Ritchie has just been born :)
It does look curious but ~0& has no effect on 0x1f<<1 at all. A bit-wise
and of all ones yields the 'other' operand. I don't see that ones
complement has anything to do with it.
 
B

Ben Pfaff

Joona I Palaste said:
They only apply to base10 (ten) numbers. Not mathematically elegant,
but easier to implement.

C99 has hexadecimal floating-point constants, but they are
required to have an exponent, so "0x1f" is not one.
 
M

Martin Dickopp

On a one's complement implementation, it's either undefined behaviour or
claiming that someone called Dennis Ritchie has just been born :)

As far as I can see, it is implementation-defined whether or not `~0'
produces a trap representation on a one's complement implementation.
If it doesn't, it is unspecified if it produces a negative or normal
zero.

Before the `&' operator is evaluated, the result of `~0' is converted to
`unsigned int'. Is my understanding of 6.3.1.3 correct that a negative
zero becomes a zero when converted to `unsigned int'?

If I'm right so far, the expression `~0&0x1f<<1' either causes undefined
behavior (`~0' is a trap representation) or yields the value `0' on a
one's complement implementation.

But even in the latter case, the type of `~0&0x1f<<1' is `unsigned int',
so the fact that it corresponds to a "%d" format specifier causes
undefined behavior. An implementation is therefore free to write the
string "Someone called Dennis Ritchie has just been born.\n" to standard
output. ;)

Martin
 
L

Lew Pitcher

Martin said:
As far as I can see, it is implementation-defined whether or not `~0'
produces a trap representation on a one's complement implementation.
If it doesn't, it is unspecified if it produces a negative or normal
zero.

Let me make sure that I follow your reasoning/concern here

On a ones-complement machine, A ones-complement negative zero may be a trap
representation. On such a machine, ~0 may also represent a trap value, as it
would be binary identical to an ones-complement negative zero.
Before the `&' operator is evaluated, the result of `~0' is converted to
`unsigned int'. Is my understanding of 6.3.1.3 correct that a negative
zero becomes a zero when converted to `unsigned int'?

Assuming that ~0 is not a trap representation on this ones-complement
machine, then the C code would have to convert the ones-complement negative
zero (which is indistinguishable from the intended ~0) to a positive zero
(which would be binary zero).
If I'm right so far, the expression `~0&0x1f<<1' either causes undefined
behavior (`~0' is a trap representation) or yields the value `0' on a
one's complement implementation.

Again assuming that ~0 isn't a trap value, then the arithmetical result of
anding a value with a zero (the result of the conversion of the
ones-complement negative zero to a usable positive zero) is zero.
But even in the latter case, the type of `~0&0x1f<<1' is `unsigned int',
so the fact that it corresponds to a "%d" format specifier causes
undefined behavior. An implementation is therefore free to write the
string "Someone called Dennis Ritchie has just been born.\n" to standard
output. ;)

And thus we complete the process.

Did I get it right?



--

Lew Pitcher, IT Consultant, Application Architecture
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed here are my own, not my employer's)
 
M

Mantorok Redgormor

On a one's complement implementation, it's either undefined behaviour or
claiming that someone called Dennis Ritchie has just been born :)

Dan

Joona Palaste said it performs two's complement. But I don't see how
~0 performs two's complement. When I take a look at the draft copy of
the standard it says that the result of ~ is the bitwise complement of
its operand. That means all bits are inverted. How does two's
complement come into play? and where is this stated in the standard
that ~ can be either one's complement or two's complement?
 
J

Joona I Palaste

Joona Palaste said it performs two's complement. But I don't see how
~0 performs two's complement. When I take a look at the draft copy of
the standard it says that the result of ~ is the bitwise complement of
its operand. That means all bits are inverted. How does two's
complement come into play? and where is this stated in the standard
that ~ can be either one's complement or two's complement?

Perhaps I should have explained in more detail. The ~ operator
implements one's complement arithmetic by inverting all the bits. Thus
you get "all-bits-one" for ~0, because "all-bits-zero" is 0.
But! If the number is signed, two's complement arithmetic comes into
play *after* that. On a two's complement machine, any number whose
leftmost bit is 1 is taken as negative, and "all-bits-one" is -1 on
such a machine. Therefore, on a two's complement machine, ~0 == -1.

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"When a man talks dirty to a woman, that's sexual harassment. When a woman talks
dirty to a man, that's 14.99 per minute + local telephone charges!"
- Ruben Stiller
 
D

Dan Pop

In said:
As far as I can see, it is implementation-defined whether or not `~0'
produces a trap representation on a one's complement implementation.
If it doesn't, it is unspecified if it produces a negative or normal
zero.

Correct, so far.
Before the `&' operator is evaluated, the result of `~0' is converted to
`unsigned int'.

Why? Both operands have type int.
Is my understanding of 6.3.1.3 correct that a negative
zero becomes a zero when converted to `unsigned int'?

It doesn't matter, because no such conversion occurs.
If I'm right so far, the expression `~0&0x1f<<1' either causes undefined
behavior (`~0' is a trap representation) or yields the value `0' on a
one's complement implementation.

Correct, even if you're not right so far ;-)
But even in the latter case, the type of `~0&0x1f<<1' is `unsigned int',

Why? All the operands involved have type int, so how can you end up with
an unsigned int result?!?
so the fact that it corresponds to a "%d" format specifier causes
undefined behavior.

The behaviour is well defined in this case, the expected output being
"Happy Birthday, Dennis Ritchie. 0 today.\n"
An implementation is therefore free to write the
string "Someone called Dennis Ritchie has just been born.\n" to standard
output. ;)

Which is a paraphrase of the actual output.

Dan
 
K

Keith Thompson

And an image suddenly springs to mind of Dennis Ritchie standing
behind a podium at a C conference shouting "Get a life!".

Not that I'd be any more likely to follow that advice than anyone else
in this thread. :cool:}
 

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,079
Messages
2,570,574
Members
47,206
Latest member
Zenden

Latest Threads

Top