C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Signed mod unsigned
Goto page Previous  1, 2
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C Language
View previous topic :: View next topic  
Author Message
Eric Sosman
Guest





PostPosted: Thu Jun 07, 2012 9:58 pm    Post subject: Re: Signed mod unsigned Reply with quote



On 6/7/2012 3:58 PM, Ben Bacarisse wrote:
Quote:
Eric Sosman<esosman@ieee-dot-org.invalid> writes:

On 6/7/2012 7:29 AM, BartC wrote:
Johannes Bauer"<dfnsonfsduifb (AT) gmx (DOT) de> wrote in message
news:jqpv0d$beq$1 (AT) news (DOT) albasani.net...
On 06.06.2012 16:53, gwowen wrote:

[0] My intuition, for example, tells me that -1 % 30 equals 29. My
intuition is worthless too.

Well, it's always nice when intuition at least overlaps with the reality
of compilers or interpreters :-)

BTW, -1 % 30 == 29 in Python. I did know that C did not give up the
sign, but I'd have expected for example -100 % 30 == -10 (it is 20 in
Python). Anyways, it does so for signed/signed types, so I'm going to
use these.

So -1%30 is -1 in C and 29 in Python. While -1%30u in C is 15.

-1%30u in C *can be* 15.

-1, 15 and 29; any other possible results for the same expression?

In C, the possible results are 1, 3, 7, 15.

I think -1 is also possible on those awkward systems where UINT_MAX ==
INT_MAX.

Quite right; thanks for correcting my oversight.

--
Eric Sosman
esosman@ieee-dot-org.invalid
Back to top
Tim Rentsch
Guest





PostPosted: Fri Jun 08, 2012 7:20 am    Post subject: Re: Signed mod unsigned Reply with quote



Ben Bacarisse <ben.usenet (AT) bsb (DOT) me.uk> writes:

Quote:
Eric Sosman <esosman@ieee-dot-org.invalid> writes:

On 6/7/2012 7:29 AM, BartC wrote:
Johannes Bauer" <dfnsonfsduifb (AT) gmx (DOT) de> wrote in message
news:jqpv0d$beq$1 (AT) news (DOT) albasani.net...
On 06.06.2012 16:53, gwowen wrote:

[0] My intuition, for example, tells me that -1 % 30 equals 29. My
intuition is worthless too.

Well, it's always nice when intuition at least overlaps with the reality
of compilers or interpreters :-)

BTW, -1 % 30 == 29 in Python. I did know that C did not give up the
sign, but I'd have expected for example -100 % 30 == -10 (it is 20 in
Python). Anyways, it does so for signed/signed types, so I'm going to
use these.

So -1%30 is -1 in C and 29 in Python. While -1%30u in C is 15.

-1%30u in C *can be* 15.

-1, 15 and 29; any other possible results for the same expression?

In C, the possible results are 1, 3, 7, 15.

I think -1 is also possible on those awkward systems where UINT_MAX ==
INT_MAX.

Sort of. This curious behavior was not present in C90 or
in the original C99. It was added via a TC (it appears
in N1124) as a result of Defect Report 230. However,
subsequently it was acknowledged that the strange effect
on the promotion rules was an unintended consequence of a
poor wording choice to address the DR. This has since
been corrected in C11 -- under C11 unsigned int is never
'promoted' to int even if UINT_MAX == INT_MAX. Hence the
expression -1%30u can never be -1 (or any negative number)
under the current standard.
Back to top
Johannes Bauer
Guest





PostPosted: Fri Jun 08, 2012 7:33 am    Post subject: Re: Signed mod unsigned Reply with quote



On 08.06.2012 11:20, Tim Rentsch wrote:

Quote:
I think -1 is also possible on those awkward systems where UINT_MAX ==
INT_MAX.

Sort of. This curious behavior was not present in C90 or
in the original C99. It was added via a TC (it appears
in N1124) as a result of Defect Report 230. However,
subsequently it was acknowledged that the strange effect
on the promotion rules was an unintended consequence of a
poor wording choice to address the DR. This has since
been corrected in C11 -- under C11 unsigned int is never
'promoted' to int even if UINT_MAX == INT_MAX. Hence the
expression -1%30u can never be -1 (or any negative number)
under the current standard.

Wow -- I really don't feel bad about tripping over this now. It *is*
indeed confusion and without a *lot* of insight into the standard it is
quite hard to tell what the expression will evaluate to on different
platforms.

Best regards,
Joe

--
Quote:
Wo hattest Du das Beben nochmal GENAU vorhergesagt?
Zumindest nicht öffentlich!
Ah, der neueste und bis heute genialste Streich unsere großen

Kosmologen: Die Geheim-Vorhersage.
- Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$1 (AT) speranza (DOT) aioe.org>
Back to top
Ben Bacarisse
Guest





PostPosted: Fri Jun 08, 2012 9:06 am    Post subject: Re: Signed mod unsigned Reply with quote

Tim Rentsch <txr (AT) alumni (DOT) caltech.edu> writes:

Quote:
Ben Bacarisse <ben.usenet (AT) bsb (DOT) me.uk> writes:

Eric Sosman <esosman@ieee-dot-org.invalid> writes:
snip
-1%30u in C *can be* 15.

-1, 15 and 29; any other possible results for the same expression?

In C, the possible results are 1, 3, 7, 15.

I think -1 is also possible on those awkward systems where UINT_MAX ==
INT_MAX.

Sort of. This curious behavior was not present in C90 or
in the original C99. It was added via a TC (it appears
in N1124) as a result of Defect Report 230. However,
subsequently it was acknowledged that the strange effect
on the promotion rules was an unintended consequence of a
poor wording choice to address the DR. This has since
been corrected in C11 -- under C11 unsigned int is never
'promoted' to int even if UINT_MAX == INT_MAX. Hence the
expression -1%30u can never be -1 (or any negative number)
under the current standard.

Well that's pleasing to know, although I've never had to wrestle with
such an implementation. As far as I can tell, if it followed C99 to the
letter, the only way to do unsigned arithmetic would be to force one or
more of the operands to be "wider" than unsigned int. I put wider in
quotes because I think you can do it even if there no type that is
actually wider because of the way conversion rank is defined. Thus
-1%30ul can't be -1 even on the most literal C99 implementation.

Still, it's good that this has been tidied up. It will save much
nit-picking time here. I wonder if it will have any other effect on the
world.

--
Ben.
Back to top
Ben Bacarisse
Guest





PostPosted: Fri Jun 08, 2012 9:30 am    Post subject: Re: Signed mod unsigned Reply with quote

Johannes Bauer <dfnsonfsduifb (AT) gmx (DOT) de> writes:

Quote:
On 08.06.2012 11:20, Tim Rentsch wrote:

I think -1 is also possible on those awkward systems where UINT_MAX ==
INT_MAX.

Sort of. This curious behavior was not present in C90 or
in the original C99. It was added via a TC (it appears
in N1124) as a result of Defect Report 230. However,
subsequently it was acknowledged that the strange effect
on the promotion rules was an unintended consequence of a
poor wording choice to address the DR. This has since
been corrected in C11 -- under C11 unsigned int is never
'promoted' to int even if UINT_MAX == INT_MAX. Hence the
expression -1%30u can never be -1 (or any negative number)
under the current standard.

Wow -- I really don't feel bad about tripping over this now. It *is*
indeed confusion and without a *lot* of insight into the standard it is
quite hard to tell what the expression will evaluate to on different
platforms.

I don't want to make you feel bad again, but this last case is one of
the oddest corners of C and can be quite safely ignored by almost
everyone (indeed by everyone, soon, if C11 gets a hold).

The main fact, that mixed int and unsigned int arithmetic is done by
converting the int operand to unsigned int, is commonplace and needs to
be kept in mind for those times when it will matter. The fact that it's
happening is often masked by implementations that use 2's complement and
define the unsigned to int conversion as simply "stuffing the bits back
in there". However

int x;
/* ... */
x = x + 1u;

can raise a signal when x is, say, -1 on systems that define the
conversion of out-of-range values to int as doing so. On most systems
it "just works" as if 1 had been used in place of 1u. Real examples are
often more disguised since you might be adding a size_t value to x.

The fact that -1 % 30u can have different values on different systems is
just a reflection of the fact that UINT_MAX can have different values
depending on the number of bits used by unsigned int.

So, once again, my intent is not to make you feel you should have known
all this, but simply to say that it is *worth* knowing, and that it's
not actually as complicated as this thread seems to suggest.

--
Ben.
Back to top
Tim Rentsch
Guest





PostPosted: Fri Jun 08, 2012 4:05 pm    Post subject: Re: Signed mod unsigned Reply with quote

Johannes Bauer <dfnsonfsduifb (AT) gmx (DOT) de> writes:

Quote:
On 08.06.2012 11:20, Tim Rentsch wrote:

I think -1 is also possible on those awkward systems where
UINT_MAX == INT_MAX.

Sort of. This curious behavior was not present in C90 or
in the original C99. It was added via a TC (it appears
in N1124) as a result of Defect Report 230. However,
subsequently it was acknowledged that the strange effect
on the promotion rules was an unintended consequence of a
poor wording choice to address the DR. This has since
been corrected in C11 -- under C11 unsigned int is never
'promoted' to int even if UINT_MAX == INT_MAX. Hence the
expression -1%30u can never be -1 (or any negative number)
under the current standard.

Wow -- I really don't feel bad about tripping over this now.
It *is* indeed confusion and without a *lot* of insight into
the standard it is quite hard to tell what the expression will
evaluate to on different platforms.

In practice it isn't hard to say what the result will be, because
the "pathological" implementations with such bizarre behavior are
very rare (indeed, I conjecture that none exist), and very likely
a developer would know if his platform had such issues. Granted,
the rule for converting the signed type to the unsigned type does
need to be known, but people who use mixed-mode arithmetic should
be familiar with that for other reasons (eg, comparisons).

When C was originally standardized, there was a big debate about
how to do integer promotions (in particular, should types like
'unsigned short' promote to signed int or unsigned int?). So
here's another case for you:

unsigned short us_30 = 30;
unsigned int ui_30 = 30;
int minus_one = -1;

// now, what is the result of

if( minus_one % us_30 == minus_one % ui_30 ) ... etc ...

Does the "etc" get executed or not? You might enjoy looking
into the Standard and see what you can make of this question.
Back to top
Tim Rentsch
Guest





PostPosted: Fri Jun 08, 2012 4:12 pm    Post subject: Re: Signed mod unsigned Reply with quote

Ben Bacarisse <ben.usenet (AT) bsb (DOT) me.uk> writes:

Quote:
Johannes Bauer <dfnsonfsduifb (AT) gmx (DOT) de> writes:

On 08.06.2012 11:20, Tim Rentsch wrote:

I think -1 is also possible on those awkward systems where UINT_MAX ==
INT_MAX.

Sort of. This curious behavior was not present in C90 or
in the original C99. It was added via a TC (it appears
in N1124) as a result of Defect Report 230. However,
subsequently it was acknowledged that the strange effect
on the promotion rules was an unintended consequence of a
poor wording choice to address the DR. This has since
been corrected in C11 -- under C11 unsigned int is never
'promoted' to int even if UINT_MAX == INT_MAX. Hence the
expression -1%30u can never be -1 (or any negative number)
under the current standard.

Wow -- I really don't feel bad about tripping over this now. It *is*
indeed confusion and without a *lot* of insight into the standard it is
quite hard to tell what the expression will evaluate to on different
platforms.

I don't want to make you feel bad again, but this last case is one of
the oddest corners of C and can be quite safely ignored by almost
everyone (indeed by everyone, soon, if C11 gets a hold).

The main fact, that mixed int and unsigned int arithmetic is done by
converting the int operand to unsigned int, is commonplace and needs to
be kept in mind for those times when it will matter. The fact that it's
happening is often masked by implementations that use 2's complement and
define the unsigned to int conversion as simply "stuffing the bits back
in there". However

int x;
/* ... */
x = x + 1u;

can raise a signal when x is, say, -1 on systems that define the
conversion of out-of-range values to int as doing so. [snip]

Forgive me if this is a stupid question -- can you explain how
starting with x == -1 can give rise to anything other than x == 0
after the assignment? To me the behavior here looks well-defined.
Back to top
Tim Rentsch
Guest





PostPosted: Fri Jun 08, 2012 4:32 pm    Post subject: Re: Signed mod unsigned Reply with quote

Ben Bacarisse <ben.usenet (AT) bsb (DOT) me.uk> writes:

Quote:
Tim Rentsch <txr (AT) alumni (DOT) caltech.edu> writes:

Ben Bacarisse <ben.usenet (AT) bsb (DOT) me.uk> writes:

Eric Sosman <esosman@ieee-dot-org.invalid> writes:
snip
-1%30u in C *can be* 15.

-1, 15 and 29; any other possible results for the same expression?

In C, the possible results are 1, 3, 7, 15.

I think -1 is also possible on those awkward systems where UINT_MAX ==
INT_MAX.

Sort of. This curious behavior was not present in C90 or
in the original C99. It was added via a TC (it appears
in N1124) as a result of Defect Report 230. However,
subsequently it was acknowledged that the strange effect
on the promotion rules was an unintended consequence of a
poor wording choice to address the DR. This has since
been corrected in C11 -- under C11 unsigned int is never
'promoted' to int even if UINT_MAX == INT_MAX. Hence the
expression -1%30u can never be -1 (or any negative number)
under the current standard.

Well that's pleasing to know, although I've never had to
wrestle with such an implementation. As far as I can tell, if
it followed C99 to the letter, the only way to do unsigned
arithmetic would be to force one or more of the operands to be
"wider" than unsigned int. [snip]

Most likely there are no such implementations. Assuming
however that such hardware platforms still exist, implementors
determined to do a C99 implementation on them would be well
advised to have INT_MAX == UINT_MAX/2 + 1, by making the
high-order bit of a hardware integer value be a 'padding bit'
as far as the C implementation is concerned. Taking this
approach we could still get a full range of values for
int-only operations (taking advantage of "undefined behavior"
for values that have that bit set), but signed/unsigned
mixtures would not behave pathologically.

(Under the heading of 'note to self': I really should get in
the habit of putting

#include <limits.h>
#if UINT_MAX == INT_MAX
#error UINT_MAX == INT_MAX -- need I say more
#endif

in my common header files.)
Back to top
Ben Bacarisse
Guest





PostPosted: Fri Jun 08, 2012 5:37 pm    Post subject: Re: Signed mod unsigned Reply with quote

Tim Rentsch <txr (AT) alumni (DOT) caltech.edu> writes:

Quote:
Ben Bacarisse <ben.usenet (AT) bsb (DOT) me.uk> writes:
snip
The main fact, that mixed int and unsigned int arithmetic is done by
converting the int operand to unsigned int, is commonplace and needs to
be kept in mind for those times when it will matter. The fact that it's
happening is often masked by implementations that use 2's complement and
define the unsigned to int conversion as simply "stuffing the bits back
in there". However

int x;
/* ... */
x = x + 1u;

can raise a signal when x is, say, -1 on systems that define the
conversion of out-of-range values to int as doing so. [snip]

Forgive me if this is a stupid question -- can you explain how
starting with x == -1 can give rise to anything other than x == 0
after the assignment? To me the behavior here looks well-defined.

Yes, I should have said "x = -2" or, indeed, any int value < 0 other
than the one I picked.

--
Ben.
Back to top
Keith Thompson
Guest





PostPosted: Fri Jun 08, 2012 6:44 pm    Post subject: Re: Signed mod unsigned Reply with quote

Tim Rentsch <txr (AT) alumni (DOT) caltech.edu> writes:
[...]
Quote:
However

int x;
/* ... */
x = x + 1u;

can raise a signal when x is, say, -1 on systems that define the
conversion of out-of-range values to int as doing so. [snip]

Forgive me if this is a stupid question -- can you explain how
starting with x == -1 can give rise to anything other than x == 0
after the assignment? To me the behavior here looks well-defined.

I was in the middle of explaining why it's not well-defined when
I realized that it actually is.

The operands of "+" are of types int and unsigned int. The "usual
arithmetic conversions" cause the left operand to be converted
from int to unsigned int. The int value -1 is outside the range of
the target type -- but int-to-unsigned conversion is well defined,
and yields UINT_MAX. UINT_MAX + 1u yields 0u, and the assignment
converts 0u (type unsigned int) to 0 (type int).

--
Keith Thompson (The_Other_Keith) kst-u (AT) mib (DOT) org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Back to top
Ben Bacarisse
Guest





PostPosted: Fri Jun 08, 2012 7:22 pm    Post subject: Re: Signed mod unsigned Reply with quote

Keith Thompson <kst-u (AT) mib (DOT) org> writes:

Quote:
Tim Rentsch <txr (AT) alumni (DOT) caltech.edu> writes:
[...]
However

int x;
/* ... */
x = x + 1u;

can raise a signal when x is, say, -1 on systems that define the
conversion of out-of-range values to int as doing so. [snip]

Forgive me if this is a stupid question -- can you explain how
starting with x == -1 can give rise to anything other than x == 0
after the assignment? To me the behavior here looks well-defined.

I was in the middle of explaining why it's not well-defined when
I realized that it actually is.

The operands of "+" are of types int and unsigned int. The "usual
arithmetic conversions" cause the left operand to be converted
from int to unsigned int. The int value -1 is outside the range of
the target type -- but int-to-unsigned conversion is well defined,
and yields UINT_MAX. UINT_MAX + 1u yields 0u, and the assignment
converts 0u (type unsigned int) to 0 (type int).

Yes. Originally I wrote it without an example value for x, but then I
thought "I'll give an example value to make it concrete" and I went and
chose the only negative value that invalidate the example!

--
Ben.
Back to top
Johannes Bauer
Guest





PostPosted: Sun Jun 10, 2012 6:56 am    Post subject: Re: Signed mod unsigned Reply with quote

On 08.06.2012 13:30, Ben Bacarisse wrote:

Quote:
I don't want to make you feel bad again, but this last case is one of
the oddest corners of C and can be quite safely ignored by almost
everyone (indeed by everyone, soon, if C11 gets a hold).

No worries, you haven't made me feel bad again :-)

Much rather curious: In what ways does C11 change this behavior? I
haven't looked into C11 at all yet and am really interested what that
change could be (while still remaining backwards compatible).

Best regards,
Joe

--
Quote:
Wo hattest Du das Beben nochmal GENAU vorhergesagt?
Zumindest nicht öffentlich!
Ah, der neueste und bis heute genialste Streich unsere großen

Kosmologen: Die Geheim-Vorhersage.
- Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$1 (AT) speranza (DOT) aioe.org>
Back to top
Ben Bacarisse
Guest





PostPosted: Sun Jun 10, 2012 11:40 am    Post subject: Re: Signed mod unsigned Reply with quote

Johannes Bauer <dfnsonfsduifb (AT) gmx (DOT) de> writes:

Quote:
On 08.06.2012 13:30, Ben Bacarisse wrote:

I don't want to make you feel bad again, but this last case is one of
the oddest corners of C and can be quite safely ignored by almost
everyone (indeed by everyone, soon, if C11 gets a hold).

No worries, you haven't made me feel bad again :-)

Much rather curious: In what ways does C11 change this behavior? I
haven't looked into C11 at all yet and am really interested what that
change could be (while still remaining backwards compatible).

What's happened (thanks, Tim, for making me go look) is that the phrase
"other than int or unsigned int" has been added to exclude them from the
integer promotions. This means that unsigned int is never promoted to
int, even on those odd systems where the rule would otherwise apply ("if
an int can represent all of the values of the original type [...] the
value is converted to an int").

This is not backwards compatible on those odd implementations, but since
it seems the effect of the old rule on unsigned int was introduced
inadvertently, the committee must have felt it worth breaking
compatibility to tidy this up.

--
Ben.
Back to top
Keith Thompson
Guest





PostPosted: Mon Jun 11, 2012 8:49 pm    Post subject: Re: Signed mod unsigned Reply with quote

Ben Bacarisse <ben.usenet (AT) bsb (DOT) me.uk> writes:
Quote:
Johannes Bauer <dfnsonfsduifb (AT) gmx (DOT) de> writes:
On 08.06.2012 13:30, Ben Bacarisse wrote:
I don't want to make you feel bad again, but this last case is one of
the oddest corners of C and can be quite safely ignored by almost
everyone (indeed by everyone, soon, if C11 gets a hold).

No worries, you haven't made me feel bad again :-)

Much rather curious: In what ways does C11 change this behavior? I
haven't looked into C11 at all yet and am really interested what that
change could be (while still remaining backwards compatible).

What's happened (thanks, Tim, for making me go look) is that the phrase
"other than int or unsigned int" has been added to exclude them from the
integer promotions. This means that unsigned int is never promoted to
int, even on those odd systems where the rule would otherwise apply ("if
an int can represent all of the values of the original type [...] the
value is converted to an int").

This is not backwards compatible on those odd implementations, but since
it seems the effect of the old rule on unsigned int was introduced
inadvertently, the committee must have felt it worth breaking
compatibility to tidy this up.

It's not backwards compatible with implementations where an int can old
all the values of unsigned int that followed the letter of the standard.

I rather doubt that there are any such implementations in the real
world. My guess (and it's only a guess) is that there are very few
implementations with UINT_MAX == INT_MAX, and of those implementations
few if any fully conformed to C99.

--
Keith Thompson (The_Other_Keith) kst-u (AT) mib (DOT) org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Back to top
Tim Rentsch
Guest





PostPosted: Sun Jun 24, 2012 2:32 pm    Post subject: Re: Signed mod unsigned Reply with quote

Ben Bacarisse <ben.usenet (AT) bsb (DOT) me.uk> writes:

Quote:
Johannes Bauer <dfnsonfsduifb (AT) gmx (DOT) de> writes:

On 08.06.2012 13:30, Ben Bacarisse wrote:

I don't want to make you feel bad again, but this last case is one of
the oddest corners of C and can be quite safely ignored by almost
everyone (indeed by everyone, soon, if C11 gets a hold).

No worries, you haven't made me feel bad again :-)

Much rather curious: In what ways does C11 change this behavior? I
haven't looked into C11 at all yet and am really interested what that
change could be (while still remaining backwards compatible).

What's happened (thanks, Tim, for making me go look) is that the phrase
"other than int or unsigned int" has been added to exclude them from the
integer promotions. This means that unsigned int is never promoted to
int, even on those odd systems where the rule would otherwise apply ("if
an int can represent all of the values of the original type [...] the
value is converted to an int").

This is not backwards compatible on those odd implementations, but since
it seems the effect of the old rule on unsigned int was introduced
inadvertently, the committee must have felt it worth breaking
compatibility to tidy this up.

I think of this not as an incompatibility but just as correcting a
mistake that they (may have) thought no one implemented anyway.
Remember, this behavior was not in C99 originally; it was added
in a TC. For an implementation to be affected by it, it would
require: one, that the change in the TC be noticed; two, that
the implementor realize the consequences of the bad wording on
such promotions; and three, that the implementation be one of
those for which the bad wording was relevant. The likelihood of
all three of those occurring, especially given the relative lack
of attention given to C99 and the dearth of fulling conforming C99
compilers, seems low enough to make concerns about compatibility
be pretty much a non-issue.
Back to top
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C Language All times are GMT
Goto page Previous  1, 2
Page 2 of 2

 
 


Powered by phpBB © 2001, 2006 phpBB Group