~ operator returns signed value

R

RezaRob

gcc is clearly returning -1 when I do this
~ (unsigned short) 0

which is not the case if "unsigned int" is used instead of "unsigned
short".

What does the C standard say about that? (reference to the standard
is appreciated.)

Thanks.

Reza.
 
P

pete

RezaRob said:
gcc is clearly returning -1 when I do this
~ (unsigned short) 0

which is not the case if "unsigned int" is used instead of "unsigned
short".

What does the C standard say about that? (reference to the standard
is appreciated.)

If INT_MAX is greater than or equal to USHRT_MAX,
then (~ (unsigned short) 0) means the same thing as
(~ (int)(unsigned short) 0).



ISO/IEC 9899: 1990
6.2.1 Arithmetic operands
6.2.1.1 Characters and integers
A char, a short int, or an int bit-field,
or their signed or unsigned varieties,
or an enumeration type, may be used in an expression
wherever an int or unsigned int may be used.
If an int can represent all values of the original type,
the value is converted to an int; otherwise,
it is converted to an unsigned int.
These are called the integral romotions.
All other arithmetic types are unchanged by the integral promotions.
 
P

pete

pete said:
If INT_MAX is greater than or equal to USHRT_MAX,
then (~ (unsigned short) 0) means the same thing as
(~ (int)(unsigned short) 0).

ISO/IEC 9899: 1990
6.2.1 Arithmetic operands
6.2.1.1 Characters and integers
A char, a short int, or an int bit-field,
or their signed or unsigned varieties,
or an enumeration type, may be used in an expression
wherever an int or unsigned int may be used.
If an int can represent all values of the original type,
the value is converted to an int; otherwise,
it is converted to an unsigned int.
These are called the integral romotions.

That should be "These are called the integral promotions."
 
R

RezaRob

If INT_MAX is greater than or equal to USHRT_MAX,
then (~ (unsigned short) 0) means the same thing as
(~ (int)(unsigned short) 0).

ISO/IEC 9899: 1990
6.2.1 Arithmetic operands
6.2.1.1 Characters and integers
[...]

Pete, I really appreciate this.

Reza.
 
P

pete

RezaRob said:
If INT_MAX is greater than or equal to USHRT_MAX,
then (~ (unsigned short) 0) means the same thing as
(~ (int)(unsigned short) 0).

ISO/IEC 9899: 1990
6.2.1 Arithmetic operands
6.2.1.1 Characters and integers
[...]

Pete, I really appreciate this.

The following three expressions have the same type and value:
(USHRT_MAX)
((unsigned short) ~0u)
((unsigned short) -1)
 
M

Martin Wells

The following three expressions have the same type and value:
(USHRT_MAX)
((unsigned short) ~0u)
((unsigned short) -1)

Are you sure about the middle one?

1: 0u is of type unsigned int.

2: ~0u is of type unsigned int and is equal to UINT_MAX.

3: (unsigned short)~0u will be UINT_MAX % USHRT_MAX, or at least I
think it will, so it can't be USHRT_MAX.

but of course I'm open to correction!

Martin
 
R

Richard Heathfield

Martin Wells said:
Are you sure about the middle one?

1: 0u is of type unsigned int.

2: ~0u is of type unsigned int and is equal to UINT_MAX.

3: (unsigned short)~0u will be UINT_MAX % USHRT_MAX, or at least I
think it will, so it can't be USHRT_MAX.

but of course I'm open to correction!

Oh good. :) Re your Point 3, a single counter-example should suffice.
Consider a system with UINT_MAX == USHRT_MAX (e.g. typical 1990s MS-DOS
systems, or an SIL64 system such as at least one Cray. Clearly, on such a
system, UINT_MAX % USHRT_MAX will be 0 (for the same reason that x % x is
0), and yet (unsigned short)~0u will be equivalent to ~0u, which is most
emphatically NOT 0.
 
M

Martin Wells

Richard:
Oh good. :) Re your Point 3, a single counter-example should suffice.
Consider a system with UINT_MAX == USHRT_MAX (e.g. typical 1990s MS-DOS
systems, or an SIL64 system such as at least one Cray. Clearly, on such a
system, UINT_MAX % USHRT_MAX will be 0 (for the same reason that x % x is
0), and yet (unsigned short)~0u will be equivalent to ~0u, which is most
emphatically NOT 0.


Sorry I've red that a few times but I still don't understand what
you're saying.

Was pete right or wrong?

Martin
 
R

Richard Heathfield

Martin Wells said:
Richard:



Sorry I've red that a few times but I still don't understand what
you're saying.

You claimed that "(unsigned short)~0u will be UINT_MAX % USHRT_MAX". I
disputed that claim, by pointing out a counter-example.
Was pete right or wrong?

Presumably. :)
 
M

Martin Wells

Richard:
Presumably. :)


I'm still lost. I'll try think it through using MS-DOS as an example:

1: 0u == the number 0
2: ~0u == UINT_MAX == the number 65535
3: (unsigned short)~0u == the number USHRT_MAX % 65535 == the
number 65535 % 65535 == the number 0.

This leads me to believe that pete was wrong... unless I'm missing
something.

Martin
 
R

Richard Heathfield

Martin Wells said:
Richard:



I'm still lost.

3: (unsigned short)~0u == the number USHRT_MAX % 65535 == the
number 65535 % 65535 == the number 0.

Please explain why you think this is the case. I can see no justification
for your assumption that (unsigned short)~0u is equal to USHRT_MAX % 65535
(and yes, I know we're talking 16-bit systems. You originally wrote that
it's equal to UINT_MAX % USHRT_MAX, which is also incorrect.

You might reasonably claim that, on a 16-bit system, (unsigned short)~0u is
equal to UINT_MAX % (USHRT_MAX + 1), but that would just be equal to
UINT_MAX (and indeed USHRT_MAX).
This leads me to believe that pete was wrong... unless I'm missing
something.

You appear to be missing a + 1. :)
 
P

pete

Martin said:
Are you sure about the middle one?

1: 0u is of type unsigned int.

2: ~0u is of type unsigned int and is equal to UINT_MAX.

3: (unsigned short)~0u will be UINT_MAX % USHRT_MAX, or at least I
think it will, so it can't be USHRT_MAX.

but of course I'm open to correction!

This part of your post: "UINT_MAX % USHRT_MAX"
is wrong.
 
M

Martin Wells

pete:
The following three expressions have the same type and value:
(USHRT_MAX)
((unsigned short) ~0u)
((unsigned short) -1)


I'm gonna give the middle one another go. . .

Before I begin though, I'm gonna pretend I'm working with the
following machine:

CHAR_BIT == 11
sizeof(short) == 2 (all 22 bits are value bits)
sizeof(int) == 3 (31 bits are value bits, 1 is padding)

Therefore, we have:

UINT_MAX = 2147483647
USHRT_MAX = 4194303

1: 0u

Expression Type: unsigned int
Expression Value: 0

2: ~0u

Expression Type: unsigned int
Expression Value: 2147483647 (i.e. UINT_MAX)

3: (unsigned short)~0u

== UINT_MAX % (USHRT_MAX + 1)
== 2147483647 % 4194304
== 4194303

Oh, so that worked out OK. I suppose what I was tryna get my head
around from the start was how you could so blindy make the assumption

Given: a is a positive integer
b is a positive integer
a is greater than or equal to b
That:

( pow(2,a) - 1 ) % pow(2,b)

is equal to:

pow(2,b) - 1

Martin
 
P

pete

Martin said:
pete:


I'm gonna give the middle one another go. . .

Before I begin though, I'm gonna pretend I'm working with the
following machine:

CHAR_BIT == 11
sizeof(short) == 2 (all 22 bits are value bits)
sizeof(int) == 3 (31 bits are value bits, 1 is padding)

Therefore, we have:

UINT_MAX = 2147483647
USHRT_MAX = 4194303

1: 0u

Expression Type: unsigned int
Expression Value: 0

2: ~0u

Expression Type: unsigned int
Expression Value: 2147483647 (i.e. UINT_MAX)

3: (unsigned short)~0u

== UINT_MAX % (USHRT_MAX + 1)
== 2147483647 % 4194304
== 4194303

Oh, so that worked out OK.

Actually, I got one of those wrong.
The type of USHRT_MAX isn't unsigned short.
 

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
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top