Re: a DWORD with all bits set...

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



On Wed, 03 Jun 2009 14:59:04 -0500, "Doug Harrison [MVP]"
<dsh@xxxxxxxx> wrote:

On Wed, 03 Jun 2009 14:55:29 -0400, r norman <r_s_norman@xxxxxxxxxxx>
wrote:

On Wed, 03 Jun 2009 12:58:49 -0500, "Doug Harrison [MVP]"
<dsh@xxxxxxxx> wrote:

On Wed, 03 Jun 2009 15:02:43 +0300, Ismo Salonen <Ismo.Salonen@xxxxxxxxx>
wrote:

Doug Harrison [MVP] wrote:
On Tue, 2 Jun 2009 09:38:01 -0700, JRGlide
<JRGlide@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:

When I'm concerned about data at the bit level I always use hex because it is
more explicit. So my answer would be I wouldn't use either one. I would use

DWORD dwFoo = 0xFFFFFFFF;

But you gotta count the F's, and it doesn't scale with the type. However,
for any unsigned T, this always does the right thing:

T x = -1;


Thats not entirely tue.

Yes, it is.

Thats true for all processors using 2-complement
arithmetic.

The representation of -1 does not matter for the purpose of the
signed->unsigned conversion rule, which I gave in the [*] section of my
original post. Here it is again:

[*] Note that -1 works because the result of converting a negative number x
to an unsigned type T is the least value of T congruent to x modulo 2^N,
where N is the number of bits in T. This implies T(-x)+x == 0, and in
particular, T(-1)+1 == 0.

But there exists machines with 1-complement internals (
quite rare I admit). So the only truly portable answer is imho ~0.

I already explained that ~0 works only to the extent it equals -1, which it
does *not* under one's complement, sign/magnitude, and other
representations I've never encountered in the real world. ~0 does work in
two's complement, because there ~0 == -1, but it ain't portable.

How portable the code shall be ? on current all windows computers -1 is
ok, if other architectures must be also considered then ~0.

No, you've got that exactly backwards. -1 is portable, and ~0 requires
two's complement and thus is not portable.

I accept your explanation of sign-unsigned conversion as guaranteeing
that -1, no matter how represented, yields the largest possible value
on conversion to an unsigned type.

I do NOT accept your claim about ~0 because, no matter whether
sign/magnitude, one's complement, or two's complement representation,
the number 0 is always written with all bits cleared. The ~ operator
reverses every bit. Therefore ~0 must necessarily have all bits set.

Let me see if I can clarify this. The expression ~0 is a signed int, and
what it means to have "all bits set" depends on the representation of
signed integers. If one's complement, ~0 == 0. If sign/magnitude, ~0 ==
INT_MIN. (That's what I would expect, anyway.) Neither of those evaluate to
-1. Please read the [*] part quoted above until you see the importance of
this.

The only problem is how many bits are set. If may be that 0 is
represented in 16 bits so that ~0 has only 16 bits and therefore
expanding it to a 32 bit DWORD only handles half of it.

No, the only thing that matters is the language rule, "The result of
converting a negative number x to an unsigned type T is the least value of
T congruent to x modulo 2^N, where N is the number of bits in T." To put an
exclamation point on it, this is also portable:

unsigned long x = (signed char) -1;

This portably initializes x with its largest value, the value with all bits
set. If the concept of "sign extension" comes to mind, you're thinking
about this in the wrong way. You need to think in terms of the language
rule I've been citing.

That said, your widening concern is important when you're dealing with an
unsigned type on the RHS. To quote from my earlier messages:

For ~0 to say exactly what is intended, you would have to write:

DWORD x = ~DWORD(0);
...
went on to show how to use ~0 in the
foolproof way and demonstrated it's more work and requires you to keep the
types on the LHS and the RHS in sync.

It follows that you would have problems if you were to write:

unsigned long x = ~(unsigned char) 0;

But that isn't what we've been talking about. We've been talking about
converting negative numbers to unsigned.

Actually what we really have been talking about is how to set all bits
in a DWORD. That is what the subject line says, anyway.

And what it means to have all bits set does NOT depend on arithmetic
representation, it means that all bits are set. The operator ~
inverts all bits in a value. It pays absolutely no attention to
signed/unsigned -- it just inverts bits. So if you start with a 32
bit value with all bits zero, the ~ operator will then set all 32 bits
to one.

.



Relevant Pages

  • Re: a DWORD with all bits set...
    ... The representation of -1 does not matter for the purpose of the ... does *not* under one's complement, sign/magnitude, and other ... on conversion to an unsigned type. ... expanding it to a 32 bit DWORD only handles half of it. ...
    (microsoft.public.vc.mfc)
  • Re: a DWORD with all bits set...
    ... But you gotta count the F's, and it doesn't scale with the type. ... The representation of -1 does not matter for the purpose of the ... to an unsigned type T is the least value of T congruent to x modulo 2^N, ... does *not* under one's complement, sign/magnitude, and other ...
    (microsoft.public.vc.mfc)
  • Re: representations
    ... It would be a DWORD in ... float r = ... looks like with two's complement representation and a length of 32 bits. ...
    (comp.lang.c)
  • representations
    ... I'm trying to think of what one-third looks like when represented by two's ... It would be a DWORD in ... looks like with two's complement representation and a length of 32 bits. ...
    (comp.lang.c)
  • Re: ((m) /((m)%255+1)/255%255*8 + 7-100/((m)%255+14))
    ... pure binary representation; this shall be known as the value ... If some combination of value bits was a trap representation then ... Those bits have the same value as in the unsigned type, ... Because that clause is discussing only unsigned types. ...
    (comp.lang.c)