Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

shifting negative zero

3 views
Skip to first unread message

Hallvard B Furuseth

unread,
Nov 10, 2009, 9:07:00 AM11/10/09
to
C99 6.5.7p5 (Bitwise shift operators) is:
The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1
has an unsigned type or if E1 has a signed type and a nonnegative
value, the value of the result is the integral part of the quotient
of E1 / 2**E2. If E1 has a signed type and a negative value, the
resulting value is implementation-defined.

Similar for << in 6.5.7p4, provided the result is in range.

Thus negative zero >> E2 == negative zero << E2 == 0 if E2 is in range.
Is that intentional? Speaking as a programmer it's certainly a relief,
but I assume it places a burden on implementations - unless shift
instructions on existing hardware take care of it so it's a non-problem.

Could the Rationale or standard get a note about why this was decided
that way (if it was)? As far as I can tell there isn't anything now.
Same for 6.2.6.2p3: + - * / % can preserve a negative zero but not
generate a new one, e.g. -1 + 1 may not produce negative zero even
though that could be natural with one's complement.

BTW, one nitpick with the above quoted paragraph:
"the value of the result is the integral part of the quotient of
E1 / 2**E2"
Presumably that refers to mathematical rather than C integer division, so
negative zero >> 1 and negative zero / 2 can behave differently? I.e.
one can produce negative zero while the other does not.

--
Hallvard

Charlie Gordon

unread,
Nov 10, 2009, 2:52:58 PM11/10/09
to
"Hallvard B Furuseth" <h.b.fu...@usit.uio.no> a �crit dans le message de
news: hbf.2009...@bombur.uio.no...

Interesting, but moot point : no current hardware implements negative zeroes
of the integer kind, nor one's complement or even sign magnitude
representation. Why not get rid of these historical oddities in the next
version of the C Standard ?

--
Chqrlie


lawrenc...@siemens.com

unread,
Nov 10, 2009, 8:09:16 PM11/10/09
to
Hallvard B Furuseth <h.b.fu...@usit.uio.no> wrote:
> C99 6.5.7p5 (Bitwise shift operators) is:
> The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1
> has an unsigned type or if E1 has a signed type and a nonnegative
> value, the value of the result is the integral part of the quotient
> of E1 / 2**E2. If E1 has a signed type and a negative value, the
> resulting value is implementation-defined.
>
> Similar for << in 6.5.7p4, provided the result is in range.
>
> Thus negative zero >> E2 == negative zero << E2 == 0 if E2 is in range.

I think the intent was that negative zero be considered a negative value
and thus produce an implementation-defined result.
--
Larry Jones

I hate being good. -- Calvin

Dik T. Winter

unread,
Nov 11, 2009, 11:55:37 AM11/11/09
to

I think not. Note the use of "nonnegative" rather than "positive". This
indicates that the mathematical value is meant where 0 is neither negative
nor positive (unless you are a Bourbakiist, when it is both). As 0 has
two representations only in 1-s complement and sign magnitude we see that
on such machines the compiler has to use arithmetic shift (*) rather than
logical shift for those operations on signed types which yields the same
result on positive representations, unless there is overflow.

As all 1-s complement machines I have used did have an arithmetic shift it
would pose no problem. The only machine without it (Cray) was 2-s complement.
---
(*) Arithmetic shift:

Sign magnitude: the sign bit does not participate in the shift, vacated bits
are filled with 0

1-s complement: the sign bit does or does not participate in the shift, in
both cases vacated bits are filled with copies of the sign bit (there is
only a difference in case of overflow).
--
dik t. winter, cwi, science park 123, 1098 xg amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

Dik T. Winter

unread,
Nov 11, 2009, 12:01:44 PM11/11/09
to
See also my other follow-up.

In article <hbf.2009...@bombur.uio.no> Hallvard B Furuseth <h.b.fu...@usit.uio.no> writes:
...


> Same for 6.2.6.2p3: + - * / % can preserve a negative zero but not
> generate a new one, e.g. -1 + 1 may not produce negative zero even
> though that could be natural with one's complement.

Of the 1-s complement machines I have used only one was -0 preferent, i.e.
adding two values of different sign would yield -0, all other machines were
+0 preferent and would yield +0 in that case. (The difference is only
three inverters: a + b was calculated as -((-a) + (-b)).)

> BTW, one nitpick with the above quoted paragraph:
> "the value of the result is the integral part of the quotient of
> E1 / 2**E2"
> Presumably that refers to mathematical rather than C integer division, so
> negative zero >> 1 and negative zero / 2 can behave differently? I.e.
> one can produce negative zero while the other does not.

That is certainly possible, but the mathematical result is the same.

0 new messages