Topic: Fixing left shift of negative numbers
Author: Myriachan <myriachan@gmail.com>
Date: Sun, 27 Jul 2014 19:25:59 -0700 (PDT)
Raw View
------=_Part_4643_296434472.1406514359023
Content-Type: text/plain; charset=UTF-8
It seems really broken to me that left shift of negative numbers is
completely undefined. I don't see why this is necessary at all. It goes
against everything my whole generation of programmers was taught,
especially in college classes like "discrete mathematics".
I think x << y for negative x should work like this: If the shift as
implemented as multiplies by 2 does not cause a change in the sign bit, the
result is defined; otherwise it is undefined. This definition should work
for sign-magnitude, one's-complement and two's-complement implementations.
Only sign-magnitude implementations would have some difficulty on some
hardware; depending on the hardware design, they may have to mask off the
high bit as they do the shift in order to preserve its value during the
shift if the hardware shift instruction will shift "through" the sign bit.
Sign-magnitude implementations are rare these days, so really, this
difference ought not be such a huge deal that we need to make
two's-complement and one's-complement implementations suffer some annoying
math rules that only some small percentage of C/C++ programmers even know.
(Even though shifting left a negative number is as bad as dividing by zero,
very few among C/C++ users know that this is a fatal operation with an
optimizing compiler!)
Melissa
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_4643_296434472.1406514359023
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">It seems really broken to me that left shift of negative n=
umbers is completely undefined. I don't see why this is necessary at =
all. It goes against everything my whole generation of programmers wa=
s taught, especially in college classes like "discrete mathematics".<br><br=
>I think x << y for negative x should work like this: If the sh=
ift as implemented as multiplies by 2 does not cause a change in the sign b=
it, the result is defined; otherwise it is undefined. This definition=
should work for sign-magnitude, one's-complement and two's-complement impl=
ementations.<br><br>Only sign-magnitude implementations would have some dif=
ficulty on some hardware; depending on the hardware design, they may have t=
o mask off the high bit as they do the shift in order to preserve its value=
during the shift if the hardware shift instruction will shift "through" th=
e sign bit. Sign-magnitude implementations are rare these days, so re=
ally, this difference ought not be such a huge deal that we need to make tw=
o's-complement and one's-complement implementations suffer some annoying ma=
th rules that only some small percentage of C/C++ programmers even know.&nb=
sp; (Even though shifting left a negative number is as bad as dividing by z=
ero, very few among C/C++ users know that this is a fatal operation with an=
optimizing compiler!)<br><br>Melissa<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4643_296434472.1406514359023--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Sun, 27 Jul 2014 21:28:17 -0700
Raw View
On Sunday 27 July 2014 19:25:59 Myriachan wrote:
> I think x << y for negative x should work like this: If the shift as
> implemented as multiplies by 2 does not cause a change in the sign bit, the
> result is defined; otherwise it is undefined. This definition should work
> for sign-magnitude, one's-complement and two's-complement implementations.
How does this change anything?
Since a left shifting of a negative number may change the sign in one's and
two's complement (depending on the second-to-last bit), the result is undefined
as per your rule.
So it's undefined for most people.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: David Krauss <potswa@gmail.com>
Date: Mon, 28 Jul 2014 12:31:28 +0800
Raw View
On 2014-07-28, at 12:28 PM, Thiago Macieira <thiago@macieira.org> wrote:
> On Sunday 27 July 2014 19:25:59 Myriachan wrote:
>> I think x << y for negative x should work like this: If the shift as
>> implemented as multiplies by 2 does not cause a change in the sign bit, the
>> result is defined; otherwise it is undefined. This definition should work
>> for sign-magnitude, one's-complement and two's-complement implementations.
>
> How does this change anything?
>
> Since a left shifting of a negative number may change the sign in one's and
> two's complement (depending on the second-to-last bit), the result is undefined
> as per your rule.
>
> So it's undefined for most people.
That's true of positive numbers too. On a two's complement machine, signed and unsigned left shifts are the same operation. The signed overflow bit is defined the same way for positive and negative operands.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Myriachan <myriachan@gmail.com>
Date: Mon, 28 Jul 2014 10:12:17 -0700 (PDT)
Raw View
I'm not saying it's undefined if it *may* change the sign bit, I'm saying i=
t's undefined if it *does* change the sign bit. This means that it will be=
defined unless you overflow or underflow the result. The end definition t=
hus makes left shift an identical operation for signed and unsigned integer=
s in one's-complement and two's complement representation so long as overfl=
ow/underflow does not occur; only sign-magnitude changes.
Note that for purposes of undefinition, the result is undefined if the sign=
bit flips at any multiply by 2 along the way, even if the end result would=
have the same sign bit.
Finally, I think that if an implementation is configured such that it may s=
et <int>::is_modulo to true, regardless if whether it actually does, such a=
s in GCC and Clang -fwrapv, then overflow/underflow should be defined as (i=
nt)((unsigned)x << y). is_modulo's definition would be updated to include =
<<.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 28 Jul 2014 12:55:13 -0700
Raw View
On Monday 28 July 2014 10:12:17 Myriachan wrote:
> I'm not saying it's undefined if it *may* change the sign bit, I'm saying
> it's undefined if it *does* change the sign bit. This means that it will
> be defined unless you overflow or underflow the result. The end definition
> thus makes left shift an identical operation for signed and unsigned
> integers in one's-complement and two's complement representation so long as
> overflow/underflow does not occur; only sign-magnitude changes.
How do you define whether it changes the sign bit? Sounds to me like you're
asking for it to be "defined if it worked, undefined if it didn't", which sounds
a lot like "it's undefined". If you can't give me the rules for when it does
work reliably, what's the point?
> Note that for purposes of undefinition, the result is undefined if the sign
> bit flips at any multiply by 2 along the way, even if the end result would
> have the same sign bit.
Signed integers have UB overflow so you can't define it like that.
> Finally, I think that if an implementation is configured such that it may
> set <int>::is_modulo to true, regardless if whether it actually does, such
> as in GCC and Clang -fwrapv, then overflow/underflow should be defined as
> (int)((unsigned)x << y). is_modulo's definition would be updated to
> include <<.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: David Krauss <potswa@gmail.com>
Date: Tue, 29 Jul 2014 07:05:31 +0800
Raw View
--Apple-Mail=_BD508A49-C995-43C9-8C94-C6660B2461DF
Content-Type: text/plain; charset=ISO-8859-1
On 2014-07-29, at 3:55 AM, Thiago Macieira <thiago@macieira.org> wrote:
> How do you define whether it changes the sign bit? Sounds to me like you're
> asking for it to be "defined if it worked, undefined if it didn't", which sounds
> a lot like "it's undefined". If you can't give me the rules for when it does
> work reliably, what's the point?
The spec doesn't need to talk about a sign bit. It could only say the value is implementation-defined, as it already does for right shifts of negative values.
Like -8>>3, -1<<3 "works" on all two's-complement and most sign-magnitude machines. Only the tiny minority of one's-complement machines are the exception. And it's probably been a looong time since anyone actually built a C++ compiler for such.
A quick check shows that GCC does not flag -1<<3 as UB in a constant expression. It does flag -8<<30.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--Apple-Mail=_BD508A49-C995-43C9-8C94-C6660B2461DF
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;07–29, at 3:55 AM, Thiago Macieira <<a href=3D"mailto:thiago=
@macieira.org">thiago@macieira.org</a>> wrote:</div><br class=3D"Apple-i=
nterchange-newline"><blockquote type=3D"cite">How do you define whether it =
changes the sign bit? Sounds to me like you're <br>asking for it to be "def=
ined if it worked, undefined if it didn't", which sounds <br>a lot like "it=
's undefined". If you can't give me the rules for when it does <br>work rel=
iably, what's the point?<br></blockquote><div><br></div><div>The spec doesn=
’t need to talk about a sign bit. It could only say the value is impl=
ementation-defined, as it already does for right shifts of negative values.=
</div><div><br></div><div>Like <font face=3D"Courier">-8>>3</font>, <=
font face=3D"Courier">-1<<3</font> “works” on all two&rsq=
uo;s-complement and most sign-magnitude machines. Only the tiny minority of=
one’s-complement machines are the exception. And it’s probably=
been a looong time since anyone actually built a C++ compiler for such.</d=
iv><div><br></div><div>A quick check shows that GCC does not flag <font fac=
e=3D"Courier">-1<<3</font> as UB in a constant expression. It does fl=
ag <font face=3D"Courier">-8<<30</font>.</div><div><br></div></div></=
body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_BD508A49-C995-43C9-8C94-C6660B2461DF--
.
Author: Myriachan <myriachan@gmail.com>
Date: Mon, 28 Jul 2014 16:16:59 -0700 (PDT)
Raw View
------=_Part_112_216180878.1406589420138
Content-Type: text/plain; charset=UTF-8
On Monday, July 28, 2014 12:55:32 PM UTC-7, Thiago Macieira wrote:
>
> On Monday 28 July 2014 10:12:17 Myriachan wrote:
> > I'm not saying it's undefined if it *may* change the sign bit, I'm
> saying
> > it's undefined if it *does* change the sign bit. This means that it
> will
> > be defined unless you overflow or underflow the result. The end
> definition
> > thus makes left shift an identical operation for signed and unsigned
> > integers in one's-complement and two's complement representation so long
> as
> > overflow/underflow does not occur; only sign-magnitude changes.
>
> How do you define whether it changes the sign bit? Sounds to me like
> you're
> asking for it to be "defined if it worked, undefined if it didn't", which
> sounds
> a lot like "it's undefined". If you can't give me the rules for when it
> does
> work reliably, what's the point?
>
> > Note that for purposes of undefinition, the result is undefined if the
> sign
> > bit flips at any multiply by 2 along the way, even if the end result
> would
> > have the same sign bit.
>
> Signed integers have UB overflow so you can't define it like that.
>
> > Finally, I think that if an implementation is configured such that it
> may
> > set <int>::is_modulo to true, regardless if whether it actually does,
> such
> > as in GCC and Clang -fwrapv, then overflow/underflow should be defined
> as
> > (int)((unsigned)x << y). is_modulo's definition would be updated to
> > include <<.
>
In one's-complement or two's-complement representation, x << y would be
defined when the high y+1 bits of x are equal. In sign-magnitude
representation, x << y would be defined when the magnitude portion does not
overflow.
To mathematically describe this: For x of signed type, and y of integer
type in range (std::numeric_limits<decltype(+x)>::digits, 0]:
x << y for nonnegative x is defined when x <=
std::numeric_limits<decltype(+x)>::max() / pow(2, y), with this division
rounded toward zero.
x << y for negative x is defined when x >=
std::numeric_limits<decltype(+x)>::min() / pow(2, y), with this division
rounded toward zero.
pow(2, y) is meant to be of integer type of infinite precision; I can't
write superscript y here. I don't literally mean the C function pow(), for
that would be of type double.
Justification for the rounding toward zero:
For 5 of 6 cases--the 6th case being negative numbers on
two's-complement--the maximal value is a Mersenne number, such as 0x7FFFFFFF
for a 32-bit int. The negative case on one's complement and sign-magnitude
works identically, with the inequality inverted. Dividing by some number
of bits with rounding toward zero results in something like 0x007FFFFF for
e.g. y=8. (Rounding toward zero results in the same behavior for positive
and negative.) Input x=0x007FFFFF, y=8 results in 0x7FFFFF00, which is
valid. Input x=0x00800000, y=8--x being one higher--results in 0x80000000,
which has overflowed and is therefore undefined. Thus 0x007FFFFF is the
correct highest valid input x for y=8 and 32-bit promoted x.
For the two's-complement negative case, rounding is irrelevant, because the
minimum integer is a power of two, and is thus divisible by pow(2, y). The
resulting defined domain x >= -0x00800000 occurs in the example y=8 with
32-bit promoted x.
Melissa
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_112_216180878.1406589420138
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, July 28, 2014 12:55:32 PM UTC-7, Thiago=
Macieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Monday 28 J=
uly 2014 10:12:17 Myriachan wrote:
<br>> I'm not saying it's undefined if it *may* change the sign bit, I'm=
saying
<br>> it's undefined if it *does* change the sign bit. This means =
that it will
<br>> be defined unless you overflow or underflow the result. The =
end definition
<br>> thus makes left shift an identical operation for signed and unsign=
ed
<br>> integers in one's-complement and two's complement representation s=
o long as
<br>> overflow/underflow does not occur; only sign-magnitude changes.
<br>
<br>How do you define whether it changes the sign bit? Sounds to me like yo=
u're=20
<br>asking for it to be "defined if it worked, undefined if it didn't", whi=
ch sounds=20
<br>a lot like "it's undefined". If you can't give me the rules for when it=
does=20
<br>work reliably, what's the point?
<br>
<br>> Note that for purposes of undefinition, the result is undefined if=
the sign
<br>> bit flips at any multiply by 2 along the way, even if the end resu=
lt would
<br>> have the same sign bit.
<br>
<br>Signed integers have UB overflow so you can't define it like that.
<br>
<br>> Finally, I think that if an implementation is configured such that=
it may
<br>> set <int>::is_modulo to true, regardless if whether it actua=
lly does, such
<br>> as in GCC and Clang -fwrapv, then overflow/underflow should be def=
ined as
<br>> (int)((unsigned)x << y). is_modulo's definition would =
be updated to
<br>> include <<.
<br></blockquote><br>In one's-complement or two's-complement representation=
, <span style=3D"font-family: courier new,monospace;">x << y</span>=
=20
would be defined when the high <span style=3D"font-family: courier new,mono=
space;">y+1</span> bits of <span style=3D"font-family: courier new,monospac=
e;">x</span> are equal. In=20
sign-magnitude representation, <span style=3D"font-family: courier new,mono=
space;">x << y</span> would be defined when the=20
magnitude portion does not overflow.<br><br>To mathematically describe=20
this: For <span style=3D"font-family: courier new,monospace;">x</span> of s=
igned type, and <span style=3D"font-family: courier new,monospace;">y</span=
> of integer type in range=20
(<span style=3D"font-family: courier new,monospace;">std::numeric_limits<=
;decltype(+x)>::digits</span>, <span style=3D"font-family: courier new,m=
onospace;">0</span>]:<br><br><span style=3D"font-family: courier new,monosp=
ace;">x << y</span>
for nonnegative <span style=3D"font-family: courier new,monospace;">x</spa=
n> is defined when <span style=3D"font-family: courier new,monospace;">x &l=
t;=3D=20
std::numeric_limits<decltype(+x)>::max() / pow(2, y)</span>, with thi=
s=20
division rounded toward zero.<br><span style=3D"font-family: courier new,mo=
nospace;">x << y</span> for negative <span style=3D"font-family: cour=
ier new,monospace;">x</span> is defined=20
when <span style=3D"font-family: courier new,monospace;">x >=3D std::num=
eric_limits<decltype(+x)>::min() / pow(2, y)</span>,
with this division rounded toward zero.<br><br><span style=3D"font-family:=
courier new,monospace;">pow(2, y)</span> is meant to be
of integer type of infinite precision; I can't write superscript <span sty=
le=3D"font-family: courier new,monospace;">y</span>=20
here. I don't literally mean the C function <span style=3D"font-famil=
y: courier new,monospace;">pow()</span>, for that would be of
type <span style=3D"font-family: courier new,monospace;">double</span>.<br=
><br>Justification for the rounding toward zero:<br><br>For 5 of 6=20
cases--the 6th case being negative numbers on two's-complement--the=20
maximal value is a Mersenne number, such as <span style=3D"font-family: cou=
rier new,monospace;">0x7FFFFFFF</span> for a 32-bit <span style=3D"font-fam=
ily: courier new,monospace;">
int</span>. The negative case on one's complement and sign-magnitude =
works=20
identically, with the inequality inverted. Dividing by some number of=
=20
bits with rounding toward zero results in something like <span style=3D"fon=
t-family: courier new,monospace;">0x007FFFFF</span> for=20
e.g. <span style=3D"font-family: courier new,monospace;">y=3D8</span>. =
; (Rounding toward zero results in the same behavior for=20
positive and negative.) Input <span style=3D"font-family: courier new=
,monospace;">x=3D0x007FFFFF</span>, <span style=3D"font-family: courier new=
,monospace;">y=3D8</span> results in <span style=3D"font-family: courier ne=
w,monospace;">0x7FFFFF00</span>,=20
which is valid. Input <span style=3D"font-family: courier new,monospa=
ce;">x=3D0x00800000</span>, <span style=3D"font-family: courier new,monospa=
ce;">y=3D8</span>--<span style=3D"font-family: courier new,monospace;">x</s=
pan> being one higher--results in <span style=3D"font-family: courier new,m=
onospace;">
0x80000000</span>, which has overflowed and is therefore undefined. T=
hus <span style=3D"font-family: courier new,monospace;">0x007FFFFF</span>=
=20
is the correct highest valid input <span style=3D"font-family: courier new,=
monospace;">x</span> for <span style=3D"font-family: courier new,monospace;=
">y=3D8</span> and 32-bit promoted <span style=3D"font-family: courier new,=
monospace;">x</span>.<br><br>For=20
the two's-complement negative case, rounding is irrelevant, because the=20
minimum integer is a power of two, and is thus divisible by <span style=3D"=
font-family: courier new,monospace;">pow(2, y)</span>. =20
The resulting defined domain <span style=3D"font-family: courier new,monosp=
ace;">x >=3D -0x00800000</span> occurs in the example <span style=3D"fon=
t-family: courier new,monospace;">y=3D8</span> with 32-bit promoted <span s=
tyle=3D"font-family: courier new,monospace;">x</span>.<br><br>Melissa<br></=
div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_112_216180878.1406589420138--
.
Author: David Krauss <potswa@gmail.com>
Date: Tue, 29 Jul 2014 07:25:39 +0800
Raw View
--Apple-Mail=_D96A087D-A8DC-4D79-807E-9F878299A792
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1
On 2014-07-29, at 7:16 AM, Myriachan <myriachan@gmail.com> wrote:
> In one's-complement or two's-complement representation, x << y would be d=
efined when the high y+1 bits of x are equal.
Negative numbers do not naturally shift at all in one's-complement represen=
tations. Support for such machines precludes requiring support for shifting=
negative numbers.
> x << y for nonnegative x is defined when x <=3D std::numeric_limits<declt=
ype(+x)>::max() / pow(2, y), with this division rounded toward zero.
> x << y for negative x is defined when x >=3D std::numeric_limits<decltype=
(+x)>::min() / pow(2, y), with this division rounded toward zero.
This is closer to [expr.shift] =A75.8 than your previous descriptions. It's=
usually a good idea to use the existing spec as a basis for proposals.
> Justification for the rounding toward zero:
>=20
> For 5 of 6 cases--the 6th case being negative numbers on two's-complement=
--the maximal value is a Mersenne number,
You lost me. Is this a practical application? The rounding toward zero is j=
ust how fractions are always converted to integers.
An overall justification is that GCC already implements your proposal, and =
it's the most popular C++ compiler (and the only up-to-date one targeted to=
exotic machines).
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_D96A087D-A8DC-4D79-807E-9F878299A792
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;07–29, at 7:16 AM, Myriachan <<a href=3D"mailto:myriachan@gm=
ail.com">myriachan@gmail.com</a>> wrote:</div><br class=3D"Apple-interch=
ange-newline"><blockquote type=3D"cite"><div style=3D"font-family: Helvetic=
a; font-size: 12px; font-style: normal; font-variant: normal; font-weight: =
normal; letter-spacing: normal; line-height: normal; orphans: auto; text-al=
ign: start; text-indent: 0px; text-transform: none; white-space: normal; wi=
dows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div dir=3D=
"ltr">In one's-complement or two's-complement representation, <span st=
yle=3D"font-family: 'courier new', monospace;">x << y</span> wou=
ld be defined when the high <span style=3D"font-family: 'courier new',=
monospace;">y+1</span> bits of <span style=3D"font-family: 'cour=
ier new', monospace;">x</span> are equal.</div></div></blockquote><div=
><br></div><div>Negative numbers do not naturally shift at all in one&rsquo=
;s-complement representations. Support for such machines precludes requirin=
g support for shifting negative numbers.</div><br><blockquote type=3D"cite"=
><div style=3D"font-family: Helvetica; font-size: 12px; font-style: normal;=
font-variant: normal; font-weight: normal; letter-spacing: normal; line-he=
ight: normal; orphans: auto; text-align: start; text-indent: 0px; text-tran=
sform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-=
text-stroke-width: 0px;"><div dir=3D"ltr"><span style=3D"font-family: 'cour=
ier new', monospace;">x << y</span><span class=3D"Apple-converted-spa=
ce"> </span>for nonnegative<span class=3D"Apple-converted-space"> =
;</span><span style=3D"font-family: 'courier new', monospace;">x</span><spa=
n class=3D"Apple-converted-space"> </span>is defined when<span class=
=3D"Apple-converted-space"> </span><span style=3D"font-family: 'courie=
r new', monospace;">x <=3D std::numeric_limits<decltype(+x)>::max(=
) / pow(2, y)</span>, with this division rounded toward zero.<br><span styl=
e=3D"font-family: 'courier new', monospace;">x << y</span><span class=
=3D"Apple-converted-space"> </span>for negative<span class=3D"Apple-co=
nverted-space"> </span><span style=3D"font-family: 'courier new', mono=
space;">x</span><span class=3D"Apple-converted-space"> </span>is defin=
ed when<span class=3D"Apple-converted-space"> </span><span style=3D"fo=
nt-family: 'courier new', monospace;">x >=3D std::numeric_limits<decl=
type(+x)>::min() / pow(2, y)</span>, with this division rounded toward z=
ero.<br></div></div></blockquote><div><br></div><div>This is closer to [exp=
r.shift] =A75.8 than your previous descriptions. It’s usually a good =
idea to use the existing spec as a basis for proposals.</div><br><blockquot=
e type=3D"cite"><div style=3D"font-family: Helvetica; font-size: 12px; font=
-style: normal; font-variant: normal; font-weight: normal; letter-spacing: =
normal; line-height: normal; orphans: auto; text-align: start; text-indent:=
0px; text-transform: none; white-space: normal; widows: auto; word-spacing=
: 0px; -webkit-text-stroke-width: 0px;"><div dir=3D"ltr">Justification for =
the rounding toward zero:<br><br>For 5 of 6 cases--the 6th case being negat=
ive numbers on two's-complement--the maximal value is a Mersenne number,</d=
iv></div></blockquote><br></div><div>You lost me. Is this a practical appli=
cation? The rounding toward zero is just how fractions are always converted=
to integers.</div><div><br></div><div>An overall justification is that GCC=
already implements your proposal, and it’s the most popular C++ comp=
iler (and the only up-to-date one targeted to exotic machines).</div><div><=
br></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_D96A087D-A8DC-4D79-807E-9F878299A792--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 28 Jul 2014 16:40:05 -0700
Raw View
On Monday 28 July 2014 16:16:59 Myriachan wrote:
> In one's-complement or two's-complement representation, x << y would be
> defined when the high y+1 bits of x are equal. In sign-magnitude
> representation, x << y would be defined when the magnitude portion does not
> overflow.
What if we just leave it implementation-defined?
Shifting of unsigned integers is a well-defined operation. Shifting signed
integers is implementation-defined and may change the sign bit.
Done. It works, we just don't know what it will do.
I'm not sure you considered a sign-magnitude machine that stores the sign in
the lowest bit instead of the highest. That is:
magnitude:sign shifted
0000 001:1 0000 011:0 (-1 << 1 == 3)
or 0000 001:1 0000 011:1 (-1 << 1 == -3)
Depending on whether it shifts in a zero or a sign bit.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: David Krauss <potswa@gmail.com>
Date: Tue, 29 Jul 2014 07:43:52 +0800
Raw View
On 2014-07-29, at 7:40 AM, Thiago Macieira <thiago@macieira.org> wrote:
> What if we just leave it implementation-defined?
Specifically, an implementation-defined value.
> I'm not sure you considered a sign-magnitude machine that stores the sign in
> the lowest bit instead of the highest. That is:
That's not allowed by C. C++ specifically inherits the numeric limits of C, not specifically the allowed representations, but nobody is designing machines with C++-only integer representations.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Myriachan <myriachan@gmail.com>
Date: Mon, 28 Jul 2014 18:29:42 -0700 (PDT)
Raw View
------=_Part_5617_1197379702.1406597382839
Content-Type: text/plain; charset=UTF-8
On Monday, July 28, 2014 4:40:10 PM UTC-7, Thiago Macieira wrote:
>
> On Monday 28 July 2014 16:16:59 Myriachan wrote:
> > In one's-complement or two's-complement representation, x << y would be
> > defined when the high y+1 bits of x are equal. In sign-magnitude
> > representation, x << y would be defined when the magnitude portion does
> not
> > overflow.
>
> What if we just leave it implementation-defined?
>
That would be fine by me, because that's already an improvement over the
status quo, which is undefined rather than implementation-defined.
However, I think my definition is what pretty much everyone is used to and
avoids unexpected behavior.
> Shifting of unsigned integers is a well-defined operation. Shifting signed
> integers is implementation-defined and may change the sign bit.
>
> Done. It works, we just don't know what it will do.
>
> I'm not sure you considered a sign-magnitude machine that stores the sign
> in
> the lowest bit instead of the highest. That is:
>
> magnitude:sign shifted
> 0000 001:1 0000 011:0 (-1 << 1 == 3)
> or 0000 001:1 0000 011:1 (-1 << 1 == -3)
>
> Depending on whether it shifts in a zero or a sign bit.
>
The way I defined shifting in my replies, on all sign-magnitude
implementations, shifting would have to use bit masking operations in order
to achieve correct results. Use unsigned integers if you want shifting to
match underlying memory bits; the difference between unsigned and signed
bit shifting has always been known as "logical" and "arithmetic" shifting
for a reason. Effectively, left shift becomes a multiply by 2 to the power
of the right side.
On one's-complement machines, shift left would probably have to be
implemented as a loop of add instructions to repeatedly add a number to
itself, since true shifting would have strange results.
In my opinion, the stronger burden should always be on the esoteric
architectures. That's just how I am.
Melissa
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5617_1197379702.1406597382839
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, July 28, 2014 4:40:10 PM UTC-7, Thiago =
Macieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Monday 28 Ju=
ly 2014 16:16:59 Myriachan wrote:
<br>> In one's-complement or two's-complement representation, x <<=
y would be=20
<br>> defined when the high y+1 bits of x are equal. In sign-magni=
tude=20
<br>> representation, x << y would be defined when the magnitude p=
ortion does not=20
<br>> overflow.
<br>
<br>What if we just leave it implementation-defined?
<br></blockquote><div><br>That would be fine by me, because that's already =
an improvement over the status quo, which is undefined rather than implemen=
tation-defined.<br><br>However, I think my definition is what pretty much e=
veryone is used to and avoids unexpected behavior.<br> </div><blockquo=
te class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left:=
1px #ccc solid;padding-left: 1ex;">Shifting of unsigned integers is a well=
-defined operation. Shifting signed=20
<br>integers is implementation-defined and may change the sign bit.
<br>
<br>Done. It works, we just don't know what it will do.
<br>
<br>I'm not sure you considered a sign-magnitude machine that stores the si=
gn in=20
<br>the lowest bit instead of the highest. That is:
<br>
<br> magnitude:sign &nb=
sp; <wbr> &=
nbsp; shifted
<br> 0000 001:1 &=
nbsp; &nbs=
p; 0000 011:0 (-=
1 << 1 =3D=3D 3)
<br>or 0000 001:1  =
; &n=
bsp; 0000 011:1 (-1 <=
;< 1 =3D=3D -3)
<br>
<br>Depending on whether it shifts in a zero or a sign bit.
<br></blockquote><div><br>The way I defined shifting in my replies, on all =
sign-magnitude implementations, shifting would have to use bit masking oper=
ations in order to achieve correct results. Use unsigned integers if =
you want shifting to match underlying memory bits; the difference between u=
nsigned and signed bit shifting has always been known as "logical" and "ari=
thmetic" shifting for a reason. Effectively, left shift becomes a mul=
tiply by 2 to the power of the right side.<br><br>On one's-complement machi=
nes, shift left would probably have to be implemented as a loop of add inst=
ructions to repeatedly add a number to itself, since true shifting would ha=
ve strange results.<br><br>In my opinion, the stronger burden should always=
be on the esoteric architectures. That's just how I am.<br></div><br=
>Melissa<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5617_1197379702.1406597382839--
.
Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Wed, 30 Jul 2014 06:05:53 -0700 (PDT)
Raw View
------=_Part_23_1800701499.1406725553404
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, 29 July 2014 02:29:43 UTC+1, Myriachan wrote:
>
>
> On one's-complement machines, shift left would probably have to be=20
> implemented as a loop of add instructions to repeatedly add a number to=
=20
> itself, since true shifting would have strange results.
>
=20
What=E2=80=99s wrong with negating, shifting left and negating again?
=20
To me, the only *logical* way to mandate operator<<(signed whatever,=20
unsigned whatever) would be to preserve any sign bit (e.g. on a 2=E2=80=99s=
=20
complement machine, S-x(1)-x(2)-...-x(n) << 1U should become=20
S-x(2)-x(3)-...-x(n)-0, etc. But to mandate a specific behaviour=20
could/would? make the operation inefficient.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_23_1800701499.1406725553404
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br>On Tuesday, 29 July 2014 02:29:43 UTC+1, Myriachan wr=
ote:<blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; bord=
er-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-styl=
e: solid;" class=3D"gmail_quote"><div dir=3D"ltr"><div><br>On one's-complem=
ent machines, shift left would probably have to be implemented as a loop of=
add instructions to repeatedly add a number to itself, since true shifting=
would have strange results.<br></div></div></blockquote><div> </div><=
div>What=E2=80=99s wrong with negating, shifting left and negating aga=
in?</div><div> </div><div>To me, the only <em>logical</em> way to mand=
ate operator<<(signed whatever, unsigned whatever) would be to preser=
ve any sign bit (e.g. on a 2=E2=80=99s complement machine, S-x(1)-x(2)-...-=
x(n) << 1U should become S-x(2)-x(3)-...-x(n)-0, etc. But to ma=
ndate a specific behaviour could/would? make the operation inefficient.</di=
v></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_23_1800701499.1406725553404--
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Wed, 30 Jul 2014 10:40:50 -0700 (PDT)
Raw View
------=_Part_343_193847135.1406742050242
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Can anyone mention a computer that does not use 2's complement and is=20
supported by a compiler that is being updated?=20
Den onsdagen den 30:e juli 2014 kl. 15:05:53 UTC+2 skrev Douglas Boffey:
>
>
> On Tuesday, 29 July 2014 02:29:43 UTC+1, Myriachan wrote:
>>
>>
>> On one's-complement machines, shift left would probably have to be=20
>> implemented as a loop of add instructions to repeatedly add a number to=
=20
>> itself, since true shifting would have strange results.
>>
> =20
> What=E2=80=99s wrong with negating, shifting left and negating again?
> =20
> To me, the only *logical* way to mandate operator<<(signed whatever,=20
> unsigned whatever) would be to preserve any sign bit (e.g. on a 2=E2=80=
=99s=20
> complement machine, S-x(1)-x(2)-...-x(n) << 1U should become=20
> S-x(2)-x(3)-...-x(n)-0, etc. But to mandate a specific behaviour=20
> could/would? make the operation inefficient.
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_343_193847135.1406742050242
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Can anyone mention a computer that does not use 2's comple=
ment and is supported by a compiler that is being updated? <br><br>Den=
onsdagen den 30:e juli 2014 kl. 15:05:53 UTC+2 skrev Douglas Boffey:<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><br>On Tuesday, 29 =
July 2014 02:29:43 UTC+1, Myriachan wrote:<blockquote style=3D"margin:0px =
0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-le=
ft-width:1px;border-left-style:solid" class=3D"gmail_quote"><div dir=3D"ltr=
"><div><br>On one's-complement machines, shift left would probably have to =
be implemented as a loop of add instructions to repeatedly add a number to =
itself, since true shifting would have strange results.<br></div></div></bl=
ockquote><div> </div><div>What=E2=80=99s wrong with negating, shifting=
left and negating again?</div><div> </div><div>To me, the only <=
em>logical</em> way to mandate operator<<(signed whatever, unsigned w=
hatever) would be to preserve any sign bit (e.g. on a 2=E2=80=99s complemen=
t machine, S-x(1)-x(2)-...-x(n) << 1U should become S-x(2)-x(3)-...-x=
(n)-0, etc. But to mandate a specific behaviour could/would? make the=
operation inefficient.</div></div></blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_343_193847135.1406742050242--
.
Author: Myriachan <myriachan@gmail.com>
Date: Fri, 1 Aug 2014 09:14:12 -0700 (PDT)
Raw View
------=_Part_410_1291717854.1406909652412
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, July 30, 2014 6:05:53 AM UTC-7, Douglas Boffey wrote:
>
>
> On Tuesday, 29 July 2014 02:29:43 UTC+1, Myriachan wrote:
>>
>>
>> On one's-complement machines, shift left would probably have to be=20
>> implemented as a loop of add instructions to repeatedly add a number to=
=20
>> itself, since true shifting would have strange results.
>>
> =20
> What=E2=80=99s wrong with negating, shifting left and negating again?
>
If you defined operator << this way, INT_MIN << 0 would be undefined on=20
two's-complement implementations, because -INT_MIN is undefined, and thus=
=20
wouldn't survive the first step. If (INT_MIN << 0) =3D=3D INT_MIN were=20
mandated as a special case, then your idea is actually a simple way to=20
define it.
To me, the only *logical* way to mandate operator<<(signed whatever,=20
> unsigned whatever) would be tois convenient so long as it achieves the sa=
me=20
> result. If the Standard defined shifting left as iterative multiplicatio=
n=20
> by 2, compilers would still use a shift-left immediat preserve any sign b=
it=20
> (e.g. on a 2=E2=80=99s complement machine, S-x(1)-x(2)-...-x(n) << 1U sho=
uld become=20
> S-x(2)-x(3)-...-x(n)-0, etc. But to mandate a specific behaviour=20
> could/would? make the operation inefficient.
>
The "as-if" rule of C++ means that a compiler can implement shifting more=
=20
or less whichever way it wants, so long as it returns the same result. =20
Even if the Standard defined shifting left as iterative multiplication by 2=
,=20
you can bet that x86-series compilers would still implement << 17 as "shl=
=20
eax, 17" or "imul eax, eax, 131072".
I've translated my ideas to what I think would be the Standardese. I feel=
=20
that defining the shift operators the way two's-complement processors=20
implement them in machine code is the best way to go, since this is the way=
=20
we all learn it in school or whatever learning means we used. It's also=20
the way that other programming languages that've copied C syntax work. =20
Python, Perl, Java, C#, etc. all use two's-complement semantics with their=
=20
shift operators. (And in the case of Python, the "sign bit" is considered=
=20
to be at infinity, since its integer type is arbitrary-precision.)
Non-two's-complement implementations of C/C++ already have to deal with=20
two's-complement semantics; converting from signed integer type to unsigned=
=20
integer type on such architectures is a conversion to two's-complement=20
representation ([conv.integral] 4.7.2).
(1) The shift operators << and >> group left to right.
=20
*shift-expression:* *additive-expression*
*shift-expression* << *additive-expression*
*shift-expression* >> *additive-expression*
The operands shall be of integral or unscoped enumeration type and=20
integral promotions are performed. The type of the result is the promoted=
=20
left operand. The behavior is undefined if the right operand is negative,=
=20
or greater than or equal to the length in bits of the promoted left operand=
..
(2) The value of E1 << E2 is E1 =C3=97 2^E2. If E1 has an unsigned type, =
the=20
value of this result is E1 =C3=97 2^E2 reduced modulo one more than the max=
imum=20
value representable in the result type. Otherwise, if E1 has a signed=20
type, and the implementation gives the result type modulo semantics=20
([numeric.limits.members] 18.3.2.4.60-62), then E1 =C3=97 2^E2, first reduc=
ed=20
modulo one more than the maximum value representable in the corresponding=
=20
unsigned type, converted to the result type, is the resulting value. =20
Otherwise, if E1 has a signed type, and U1 =C3=97 2^E2, where U1 is E1 conv=
erted=20
to the corresponding unsigned type of the result type, is representable in=
=20
the corresponding unsigned type of the result type, then that value,=20
converted to the result type, is the resulting value. Otherwise, the=20
behavior is undefined. [ *Note:* this operation on unsigned and=20
non-negative signed integers, as well as shift left of negative signed=20
integers on two's-complement and sign-and-magnitude implementations, has a=
=20
result equivalent to E1 left-shifted E2 bit positions, with vacated bits=20
zero-filled, if the result is defined. *=E2=80=94 end note* ] [ *Note:* by =
clause 3=20
of this paragraph, it is possible for signed integers to change their sign,=
=20
depending upon the representation. *=E2=80=94 end note* ] [ *Example:* 1 <<=
31 has=20
a value of INT_MIN on a two's-complement implementation whose int type has=
=20
32 bits, because the shift is calculated as unsigned int then converted=20
back, and that result is representable as int. This is regardless of=20
whether the implementation gives int modulo semantics. *=E2=80=94 end examp=
le* ]
(3) The value of E1 >> E2 is E1 / 2^E2, rounded toward =E2=88=92=E2=88=9E.=
[ *Example:* (-4)=20
>> 3 has a value of -1 and not 0. *=E2=80=94 end example* ] [ *Note:* on al=
l=20
integer representations, for E1 of unsigned type or E1 of signed type and=
=20
non-negative value, the result is equivalent to the integer portion of the=
=20
quotient of E1 / 2^E2. The result is also equivalent to E1 right-shifted=
=20
E2 bit positions, with vacated bits zero-filled, and with bits shifted past=
=20
the ones' position discarded. *=E2=80=94 end note* ] [ *Note:* on two's-com=
plement=20
implementations, for E1 of signed type, the result is equivalent to E1=20
right-shifted E2 bit positions, with vacated bits filled with a copy of the=
=20
sign bit, and with bits shifted past the ones' position discarded. *=E2=80=
=94 end=20
note* ]
This also requires a minor adjustment to std::numeric_limits<T>::is_modulo=
=20
to note that << is included alongside +, - and * as operators that wrap.
The changes in the above compared to the current Standard are basically=20
these:
0. No change in the rule about E2 needing to be non-negative and less than=
=20
the number of bits in E1.
1. << is fully-defined on signed integers if -fwrapv is enabled. is_modulo=
's=20
definition would change to include <<.
2. << is fully-defined on signed integers if the result, when converted to=
=20
the unsigned type, fits in the unsigned type. The unsigned type rule is=20
already in the Standard; (1 << 31) =3D=3D INT_MIN is actually already the c=
ase=20
on 32-bit two's-complement implementations by the rules of the Standard. =
=20
It's only negative values of E1 (the input value) for which my proposal=20
changes anything. Since I used conversion to unsigned as the definition,=
=20
this effectively gives it two's-complement semantics regardless of=20
implementation. It will still be undefined on overflowing the unsigned=20
type, though, as in (-2) << 31.
3. Defined >> to have two's-complement semantics.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_410_1291717854.1406909652412
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Wednesday, July 30, 2014 6:05:53 AM UTC-7, Doug=
las Boffey wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><br>On Tuesday, 29 July 2014 02:29:43 UTC+1, Myriachan wrote:<blockquo=
te style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb=
(204,204,204);border-left-width:1px;border-left-style:solid" class=3D"gmail=
_quote"><div dir=3D"ltr"><div><br>On one's-complement machines, shift left =
would probably have to be implemented as a loop of add instructions to repe=
atedly add a number to itself, since true shifting would have strange resul=
ts.<br></div></div></blockquote><div> </div><div>What=E2=80=99s wrong =
with negating, shifting left and negating again?</div></div></blockquo=
te><div><br>If you defined operator <span style=3D"font-family: courier new=
,monospace;"><<</span> this way, <span style=3D"font-family: courier =
new,monospace;">INT_MIN << 0</span> would be undefined on two's-compl=
ement implementations, because <span style=3D"font-family: courier new,mono=
space;">-INT_MIN</span> is undefined, and thus wouldn't survive the first s=
tep. If <span style=3D"font-family: courier new,monospace;">(INT_MIN =
<< 0) =3D=3D INT_MIN</span> were mandated as a special case, then you=
r idea is actually a simple way to define it.<span style=3D"font-family: co=
urier new,monospace;"></span><br><br></div><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;"><div dir=3D"ltr"><div>To me, the only <i>logical</i> way to ma=
ndate operator<<(signed whatever, unsigned whatever) would be tois co=
nvenient so long as it achieves the same result. If the Standard defi=
ned shifting left as iterative multiplication by 2, compilers would still u=
se a shift-left immediat
preserve any sign bit (e.g. on a 2=E2=80=99s complement machine,=20
S-x(1)-x(2)-...-x(n) << 1U should become S-x(2)-x(3)-...-x(n)-0,=20
etc. But to mandate a specific behaviour could/would? make the=20
operation inefficient.<br></div></div></blockquote><div><br>The "as-if" rul=
e of C++ means that a compiler can implement shifting more or less whicheve=
r way it wants, so long as it returns the same result. Even if the St=
andard defined shifting left as iterative multiplication by <span style=3D"=
font-family: courier new,monospace;">2</span>, you can bet that x86-series =
compilers would still implement <span style=3D"font-family: courier new,mon=
ospace;"><< 17</span> as "<span style=3D"font-family: courier new,mon=
ospace;">shl eax, 17</span>" or "<span style=3D"font-family: courier new,mo=
nospace;">imul eax, eax, 131072</span>".<br><br><br>I've translated my idea=
s to what I think would be the Standardese. I feel that defining the =
shift operators the way two's-complement processors implement them in machi=
ne code is the best way to go, since this is the way we all learn it in sch=
ool or whatever learning means we used. It's also the way that other =
programming languages that've copied C syntax work. Python, Perl, Jav=
a, C#, etc. all use two's-complement semantics with their shift operators.&=
nbsp; (And in the case of Python, the "sign bit" is considered to be at inf=
inity, since its integer type is arbitrary-precision.)<br><br>Non-two's-com=
plement implementations of C/C++ already have to deal with two's-complement=
semantics; converting from signed integer type to unsigned integer type on=
such architectures is a conversion to two's-complement representation ([co=
nv.integral] 4.7.2).<br><br>(1) The shift operators << and >=
> group left to right.<br> <i>shift-expression:<br></i=
> <i>additive-expression</i><br>&=
nbsp; <i>shift-expression</i> << =
<i>additive-expression</i><br> <i=
>shift-expression</i> >> <i>additive-expression</i><br> &n=
bsp; The operands shall be of integral or unscoped enumeration type and int=
egral promotions are performed. The type of the result is the promote=
d left operand. The behavior is undefined if the right operand is neg=
ative, or greater than or equal to the length in bits of the promoted left =
operand.<br><br>(2) The value of <span style=3D"font-family: courier =
new,monospace;">E1 << E2</span> is E1 =C3=97 2^E2. If E1 has an=
unsigned type, the value of this result is E1 =C3=97 2^E2 reduced modulo o=
ne more than the maximum value representable in the result type. Othe=
rwise, if E1 has a signed type, and the implementation gives the result typ=
e modulo semantics ([numeric.limits.members] 18.3.2.4.60-62), then E1 =C3=
=97 2^E2, first reduced modulo one more than the maximum value representabl=
e in the corresponding unsigned type, converted to the result type, is the =
resulting value. Otherwise, if E1 has a signed type, and U1 =C3=97 2^=
E2, where U1 is E1 converted to the corresponding unsigned type of the resu=
lt type, is representable in the corresponding unsigned type of the result =
type, then that value, converted to the result type, is the resulting value=
.. Otherwise, the behavior is undefined. [ <i>Note:</i> this ope=
ration on unsigned and non-negative signed integers, as well as shift left =
of negative signed integers on two's-complement and sign-and-magnitude impl=
ementations, has a result equivalent to E1 left-shifted E2 bit positions, w=
ith vacated bits zero-filled, if the result is defined. <i>=E2=80=94 end no=
te</i> ] [ <i>Note:</i> by clause 3 of this paragraph, it is possible for s=
igned integers to change their sign, depending upon the representation. <i>=
=E2=80=94 end note</i> ] [ <i>Example:</i> <span style=3D"font-family: cour=
ier new,monospace;">1 << 31</span> has a value of <span style=3D"font=
-family: courier new,monospace;">INT_MIN</span> on a two's-complement imple=
mentation whose <span style=3D"font-family: courier new,monospace;">int</sp=
an> type has 32 bits, because the shift is calculated as <span style=3D"fon=
t-family: courier new,monospace;">unsigned int</span> then converted back, =
and that result is representable as <span style=3D"font-family: courier new=
,monospace;">int</span>. This is regardless of whether the implementa=
tion gives <span style=3D"font-family: courier new,monospace;">int</span> m=
odulo semantics. <i>=E2=80=94 end example</i> ]<br><br>(3) The value =
of <span style=3D"font-family: courier new,monospace;">E1 >> E2</span=
> is E1 / 2^E2, rounded toward =E2=88=92=E2=88=9E. [ <i>Example:</i> =
<span style=3D"font-family: courier new,monospace;">(-4) >> 3</span> =
has a value of <span style=3D"font-family: courier new,monospace;">-1</span=
> and not <span style=3D"font-family: courier new,monospace;">0</span>. <i>=
=E2=80=94 end example</i> ] [ <i>Note:</i> on all integer representations, =
for E1 of unsigned type or E1 of signed type and non-negative value, the re=
sult is equivalent to the integer portion of the quotient of E1 / 2^E2.&nbs=
p; The result is also equivalent to E1 right-shifted E2 bit positions, with=
vacated bits zero-filled, and with bits shifted past the ones' position di=
scarded. <i>=E2=80=94 end note</i> ] [ <i>Note:</i> on two's-complement imp=
lementations, for E1 of signed type, the result is equivalent to E1 right-s=
hifted E2 bit positions, with vacated bits filled with a copy of the sign b=
it, and with bits shifted past the ones' position discarded. <i>=E2=80=94 e=
nd note</i> ]<br><br>This also requires a minor adjustment to <span style=
=3D"font-family: courier new,monospace;">std::numeric_limits<T>::is_m=
odulo</span> to note that <span style=3D"font-family: courier new,monospace=
;"><<</span> is included alongside <span style=3D"font-family: courie=
r new,monospace;">+</span>, <span style=3D"font-family: courier new,monospa=
ce;">-</span> and <span style=3D"font-family: courier new,monospace;">*</sp=
an> as operators that wrap.<br><br>The changes in the above compared to the=
current Standard are basically these:<br>0. No change in the rule about E2=
needing to be non-negative and less than the number of bits in E1.<br>1. <=
span style=3D"font-family: courier new,monospace;"><<</span> is fully=
-defined on signed integers if <span style=3D"font-family: courier new,mono=
space;">-fwrapv</span> is enabled. <span style=3D"font-family: courie=
r new,monospace;">is_modulo</span>'s definition would change to include <sp=
an style=3D"font-family: courier new,monospace;"><<</span>.<br>2. <sp=
an style=3D"font-family: courier new,monospace;"><<</span> is fully-d=
efined on signed integers if the result, when converted to the unsigned typ=
e, fits in the unsigned type. The unsigned type rule is already in th=
e Standard; <span style=3D"font-family: courier new,monospace;">(1 <<=
31) =3D=3D INT_MIN</span> is actually already the case on 32-bit two's-com=
plement implementations by the rules of the Standard. It's only negat=
ive values of E1 (the input value) for which my proposal changes anything.&=
nbsp; Since I used conversion to unsigned as the definition, this effective=
ly gives it two's-complement semantics regardless of implementation. =
It will still be undefined on overflowing the unsigned type, though, as in =
<span style=3D"font-family: courier new,monospace;">(-2) << 31</span>=
..<br>3. Defined <span style=3D"font-family: courier new,monospace;">>>=
;</span> to have two's-complement semantics.<br><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_410_1291717854.1406909652412--
.