All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laszlo Ersek <lersek@redhat.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	qemu-devel@nongnu.org, Peter Maydell <peter.maydell@linaro.org>
Subject: Re: [Qemu-devel] [PATCH v2 for 2.5] QEMU does not care about left shifts of signed negative values
Date: Tue, 17 Nov 2015 17:54:08 +0100	[thread overview]
Message-ID: <564B5BB0.2090202@redhat.com> (raw)
In-Reply-To: <87y4dwljam.fsf@blackfin.pond.sub.org>

On 11/17/15 16:47, Markus Armbruster wrote:
> Laszlo Ersek <lersek@redhat.com> writes:
> 
>> I accept this is a defensible, maybe even reasonable choice to make in
>> the QEMU project. On the other hand, I personally cannot stop hating
>> shifting negative values (any direction) -- indeed, the *original* code
>> from <https://github.com/madler/zlib/pull/112> makes me barf too.
>>
>> Therefore,
>>
>> Grudgingly-reviewed-by: Laszlo Ersek <lersek@redhat.com>
>>
>> (I realize the flag for the pointer wraparound has been separated; this
>> is strictly about shifts.)
> 
> What's so abhorrent about shifting negative values?  I know machines
> with signed integer representations other than twos complement exist, as
> do machines that can't do both logical and arithmetic shifts.  Mostly
> inside computer museums, though.
> 
> C was standardized at a time when keeping the language sufficiently
> loose to permit efficient implementation on these oddball machines made
> a lot more sense than it does now.  Making it undefined behavior went
> too far, though.  Implementation-defined or unspecified behavior would
> have sufficed.
> 
> Learn to stop worrying and love the signed shifts :)

I'm not worried. I hate it for the mental load it represents.

For me, the fact that the negative sign is encoded (with *any* kind of
representation) within the bit pattern subject to shifting, makes the
negative sign *inherently* incompatible with shifting.

In real life, *you don't shift a sign*. It just makes no sense. The sign
is not a digit. You can append or cut off zeroes from the right, but the
sign is not subject to that. The sign doesn't care.

When you shift nonzero bits out of an unsigned variable to the left, its
value changes in an intuitive, modular way. When you shift nonzero bits
out of a signed, negative value variable, to the left, it might easily
turn positive, in a completely screwed up way.

Imagine that you have five cells on paper, in real life, decimal:

+---+---+---+---+---+
| - | 3 | 0 | 9 | 0 |
+---+---+---+---+---+

you multiply it by ten ("just append a zero"), and you end up with

+---+---+---+---+---+
| 3 | 0 | 9 | 0 | 0 |
+---+---+---+---+---+

It changed sign because you ran out of cells. Now does that make any sense?

In any such case, in real life you have sign and magnitude, and the
shifting doesn't effect the sign at all!

    +---+---+---+---+
  - | 3 | 0 | 9 | 0 |
    +---+---+---+---+

You might run out of magnitude, but that's a *completely* different,
controlled and intuitive phenomenon.

... Paolo wrote

    -(a << b) works but does not express that the intention is to
    compute -a * 2^N, especially if "a" is a constant

So apparently that's where I disagree.

To me, the << operator doesn't communicate "multiply by 2^N"; it
massages the bit pattern instead. For unsigned values, said massaging
implies the multiplication *intuitively*. ("Append a zero", remember?)
It remains intuitive even if the result gets truncated.

For signed / negative values, the shifting only *happens* to imply the
multiplication, and only because of two's complement. If you shift the
negative value out of range, you're busto (the sign might change). And
even if you stay within range, two's complement is a non-intuitive, ugly
hack. It has useful properties, yes, but it's hard to reason about safely.

The problem with two's complement is not that "there could be other
representations". (No, there aren't other representations; not today.)
The problem with two's complement is that it is a mathematical construct
that is hard to reason about, despite its intentionally useful properties.

Nevermind, anyway.

Thanks
Laszlo

  reply	other threads:[~2015-11-17 16:54 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-17 14:09 [Qemu-devel] [PATCH v2 for 2.5] QEMU does not care about left shifts of signed negative values Paolo Bonzini
2015-11-17 14:47 ` Laszlo Ersek
2015-11-17 15:47   ` Markus Armbruster
2015-11-17 16:54     ` Laszlo Ersek [this message]
2015-11-17 17:06       ` Paolo Bonzini
2015-11-17 18:22       ` Markus Armbruster
2015-11-17 17:39 ` Markus Armbruster
2015-11-17 17:45   ` Paolo Bonzini
2015-11-17 18:19     ` Peter Maydell
2015-11-17 18:21       ` Paolo Bonzini
2015-11-17 18:24         ` Peter Maydell
2015-11-17 18:36           ` Paolo Bonzini
2015-11-17 18:40             ` Peter Maydell
2015-11-17 18:41           ` Markus Armbruster
2015-11-17 19:54             ` Paolo Bonzini
2015-11-17 18:24     ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=564B5BB0.2090202@redhat.com \
    --to=lersek@redhat.com \
    --cc=armbru@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.