Why write putc(s.i16 & 0xff, fp);

Discussion in 'C Programming' started by Jorge Peixoto, Oct 26, 2007.

  1. In the answer to question 12.42 of the C FAQ, we have this code:

    putc((unsigned)((s.i32 >> 24) & 0xff), fp);
    putc((unsigned)((s.i32 >> 16) & 0xff), fp);
    putc((unsigned)((s.i32 >> 8) & 0xff), fp);
    putc((unsigned)(s.i32 & 0xff), fp);


    putc((s.i16 >> 8) & 0xff, fp);
    putc(s.i16 & 0xff, fp);

    Why the & 0xff ? The putc function casts its argument to an unsigned
    char, so anything but the 8 lower bits is automatically discarded. And
    the code already assumes the a char is 8 bits.
    Jorge Peixoto, Oct 26, 2007
    #1
    1. Advertising

  2. Jorge Peixoto

    CBFalconer Guest

    Jorge Peixoto wrote:
    >
    > In the answer to question 12.42 of the C FAQ, we have this code:
    >
    > putc((unsigned)((s.i32 >> 24) & 0xff), fp);
    > putc((unsigned)((s.i32 >> 16) & 0xff), fp);
    > putc((unsigned)((s.i32 >> 8) & 0xff), fp);
    > putc((unsigned)(s.i32 & 0xff), fp);
    >
    > putc((s.i16 >> 8) & 0xff, fp);
    > putc(s.i16 & 0xff, fp);
    >
    > Why the & 0xff ? The putc function casts its argument to an unsigned
    > char, so anything but the 8 lower bits is automatically discarded. And
    > the code already assumes the a char is 8 bits.


    Where did you get the magic number 8 there? Bytes and chars can be
    any size greater or equal to 8, given by CHAR_BIT in limits.h.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>


    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Oct 26, 2007
    #2
    1. Advertising

  3. On Oct 26, 5:58 pm, CBFalconer <> wrote:
    > Jorge Peixoto wrote:
    >
    > > In the answer to question 12.42 of the C FAQ, we have this code:

    >
    > > putc((unsigned)((s.i32 >> 24) & 0xff), fp);
    > > putc((unsigned)((s.i32 >> 16) & 0xff), fp);
    > > putc((unsigned)((s.i32 >> 8) & 0xff), fp);
    > > putc((unsigned)(s.i32 & 0xff), fp);

    >
    > > putc((s.i16 >> 8) & 0xff, fp);
    > > putc(s.i16 & 0xff, fp);

    >
    > > Why the & 0xff ? The putc function casts its argument to an unsigned
    > > char, so anything but the 8 lower bits is automatically discarded. And
    > > the code already assumes the a char is 8 bits.

    >
    > Where did you get the magic number 8 there? Bytes and chars can be
    > any size greater or equal to 8, given by CHAR_BIT in limits.h


    Yes, but this code (which is from the C FAQ) already assumes that char
    is 8 bits. Read the answer to the question 12.42 of the FAQ.
    Jorge Peixoto, Oct 26, 2007
    #3
  4. Jorge Peixoto

    pete Guest

    Jorge Peixoto wrote:
    >
    > In the answer to question 12.42 of the C FAQ, we have this code:
    >
    > putc((unsigned)((s.i32 >> 24) & 0xff), fp);
    > putc((unsigned)((s.i32 >> 16) & 0xff), fp);
    > putc((unsigned)((s.i32 >> 8) & 0xff), fp);
    > putc((unsigned)(s.i32 & 0xff), fp);
    >
    > putc((s.i16 >> 8) & 0xff, fp);
    > putc(s.i16 & 0xff, fp);
    >
    > Why the & 0xff ? The putc function casts its argument to an unsigned
    > char, so anything but the 8 lower bits is automatically discarded. And
    > the code already assumes the a char is 8 bits.


    If the representation of negative integers isn't two's complement,
    then converting to unsigned char
    is different from discarding bits when s.i16 is negative.

    --
    pete
    pete, Oct 26, 2007
    #4
  5. On Oct 26, 8:46 pm, pete <> wrote:
    > Jorge Peixoto wrote:
    >
    > > In the answer to question 12.42 of the C FAQ, we have this code:

    >
    > > putc((unsigned)((s.i32 >> 24) & 0xff), fp);
    > > putc((unsigned)((s.i32 >> 16) & 0xff), fp);
    > > putc((unsigned)((s.i32 >> 8) & 0xff), fp);
    > > putc((unsigned)(s.i32 & 0xff), fp);

    >
    > > putc((s.i16 >> 8) & 0xff, fp);
    > > putc(s.i16 & 0xff, fp);

    >
    > > Why the & 0xff ? The putc function casts its argument to an unsigned
    > > char, so anything but the 8 lower bits is automatically discarded. And
    > > the code already assumes the a char is 8 bits.

    >
    > If the representation of negative integers isn't two's complement,
    > then converting to unsigned char
    > is different from discarding bits when s.i16 is negative.
    >
    > --
    > pete


    It doesn't matter.

    The standard guarantees (according to http://c-faq.com/decl/inttypes.html)
    that an unsigned char can hold any integer from 0 to 255. Since we are
    already assuming that char is 8 bits, it can hold at most 256 numbers;
    there are already 256 numbers between 0 and 255, so 0-255 is exactly
    the range of numbers that an unsigned char can hold.

    As far as I know (if I am wrong here please correct me), when you
    convert from an integer to an unsigned, shorter one, the result is the
    nonnegative remander in the division by a number that is 1 bigger
    than the maximum number that can be represented by the smaller type.
    In our case, this number is 256.

    Taking the remainder modulo 256 is equivalent to bitwise and with
    0xff, isn't it?
    Jorge Peixoto, Oct 27, 2007
    #5
  6. Jorge Peixoto

    pete Guest

    Jorge Peixoto wrote:
    >
    > On Oct 26, 8:46 pm, pete <> wrote:
    > > Jorge Peixoto wrote:
    > >
    > > > In the answer to question 12.42 of the C FAQ, we have this code:

    > >
    > > > putc((unsigned)((s.i32 >> 24) & 0xff), fp);
    > > > putc((unsigned)((s.i32 >> 16) & 0xff), fp);
    > > > putc((unsigned)((s.i32 >> 8) & 0xff), fp);
    > > > putc((unsigned)(s.i32 & 0xff), fp);

    > >
    > > > putc((s.i16 >> 8) & 0xff, fp);
    > > > putc(s.i16 & 0xff, fp);

    > >
    > > > Why the & 0xff ? The putc function casts its argument to an unsigned
    > > > char, so anything but the 8 lower bits is automatically discarded. And
    > > > the code already assumes the a char is 8 bits.

    > >
    > > If the representation of negative integers isn't two's complement,
    > > then converting to unsigned char
    > > is different from discarding bits when s.i16 is negative.
    > >
    > > --
    > > pete

    >
    > It doesn't matter.
    >
    > The standard guarantees (according to http://c-faq.com/decl/inttypes.html)
    > that an unsigned char can hold any integer from 0 to 255. Since we are
    > already assuming that char is 8 bits, it can hold at most 256 numbers;
    > there are already 256 numbers between 0 and 255, so 0-255 is exactly
    > the range of numbers that an unsigned char can hold.
    >
    > As far as I know (if I am wrong here please correct me), when you
    > convert from an integer to an unsigned, shorter one, the result is the
    > nonnegative remander in the division by a number that is 1 bigger
    > than the maximum number that can be represented by the smaller type.
    > In our case, this number is 256.
    > Taking the remainder modulo 256 is equivalent to bitwise and with
    > 0xff, isn't it?


    No.

    There are three allowable ways to represent (-1) in 16 bits:
    1111 1111 1111 1111
    1111 1111 1111 1110
    1000 0000 0000 0001

    If s.i16 has a value of (-1),
    then (s.i16 & 0xff) can have a value of either
    255, or 254, or 1.

    ((unsigned char)-1) is always equal to UCHAR_MAX.

    --
    pete
    pete, Oct 27, 2007
    #6
  7. Jorge Peixoto

    pete Guest

    CBFalconer wrote:
    >
    > Jorge Peixoto wrote:
    > >
    > > In the answer to question 12.42 of the C FAQ, we have this code:
    > >
    > > putc((unsigned)((s.i32 >> 24) & 0xff), fp);
    > > putc((unsigned)((s.i32 >> 16) & 0xff), fp);
    > > putc((unsigned)((s.i32 >> 8) & 0xff), fp);
    > > putc((unsigned)(s.i32 & 0xff), fp);
    > >
    > > putc((s.i16 >> 8) & 0xff, fp);
    > > putc(s.i16 & 0xff, fp);
    > >
    > > Why the & 0xff ?
    > > The putc function casts its argument to an unsigned char,
    > > so anything but the 8 lower bits is automatically discarded.
    > > And the code already assumes the a char is 8 bits.

    >
    > Where did you get the magic number 8 there?


    It says so, here: http://c-faq.com/stdio/extconform.html

    --
    pete
    pete, Oct 27, 2007
    #7
  8. Jorge Peixoto

    CBFalconer Guest

    Jorge Peixoto wrote:
    > pete <> wrote:
    >> Jorge Peixoto wrote:
    >>
    >>> In the answer to question 12.42 of the C FAQ, we have this code:

    >>
    >>> putc((unsigned)((s.i32 >> 24) & 0xff), fp);
    >>> putc((unsigned)((s.i32 >> 16) & 0xff), fp);
    >>> putc((unsigned)((s.i32 >> 8) & 0xff), fp);
    >>> putc((unsigned)(s.i32 & 0xff), fp);
    >>> putc((s.i16 >> 8) & 0xff, fp);
    >>> putc(s.i16 & 0xff, fp);

    >>
    >>> Why the & 0xff ? The putc function casts its argument to an
    >>> unsigned char, so anything but the 8 lower bits is automatically
    >>> discarded. And the code already assumes the a char is 8 bits.

    >>
    >> If the representation of negative integers isn't two's complement,
    >> then converting to unsigned char is different from discarding bits
    >> when s.i16 is negative.

    >
    > It doesn't matter.
    >
    > The standard guarantees (according to http://c-faq.com/decl/inttypes.html)
    > that an unsigned char can hold any integer from 0 to 255. Since we
    > are already assuming that char is 8 bits, it can hold at most 256
    > numbers; there are already 256 numbers between 0 and 255, so 0-255
    > is exactly the range of numbers that an unsigned char can hold.


    IMO the fact that the FAQ makes (and documents) assumptions about
    CHAR_BIT is no excuse for doing the same in this newsgroup,
    especially without clearly so documenting. In other words, it does
    matter, and omitting it will lead all sorts of innocent newbies
    into dingy dark despondent passages. Look with especial suspicion
    on any constant '8' in your code.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>



    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Oct 27, 2007
    #8
  9. > If s.i16 has a value of (-1),
    > then (s.i16 & 0xff) can have a value of either
    > 255, or 254, or 1.
    >
    > ((unsigned char)-1) is always equal to UCHAR_MAX.
    >
    > --
    > pete

    I didn't know that. So the bitwise operators are machine-dependent?
    Are you telling me that the following simple code

    #include <stdio.h>

    int main (void) {
    unsigned t = 256;
    t &= 0xff;
    printf ("%u\n", t);
    return 0;
    }

    is machine dependent*? I thought that the bitwise operators would
    behave as if the number is in two's complement, in any machine. It is
    amazing if the simple code above is machine dependent.

    * Even positive numbers may be represented in a crazy way. On the
    Deathstation, positive numbers are represented in base 1, that is, the
    number is the number of 1s in the variable. So 0 is all bits 0, 1 is
    1, two is 11, three is 111, etc.
    Jorge Peixoto, Oct 27, 2007
    #9
  10. Jorge Peixoto

    James Kuyper Guest

    Jorge Peixoto wrote:
    ....
    > I didn't know that. So the bitwise operators are machine-dependent?


    There are three permitted representations for negative values of signed
    integer types; which one is actually used is implementation-defined.

    The binary | and & operators are defined by the standard only in terms
    of their operations on value and sign bits; the consequences of that
    definition when applied to signed types are therefore tied to which of
    those three representations is used for negative values.

    > Are you telling me that the following simple code
    >
    > #include <stdio.h>
    >
    > int main (void) {
    > unsigned t = 256;
    > t &= 0xff;
    > printf ("%u\n", t);
    > return 0;
    > }
    >
    > is machine dependent*?


    No. You'd have to use a signed type with a negative value in order to
    get behavior that is implementation-defined.
    James Kuyper, Oct 27, 2007
    #10
  11. Jorge Peixoto

    jaysome Guest

    On Fri, 26 Oct 2007 14:17:56 -0700, Jorge Peixoto
    <> wrote:

    >On Oct 26, 5:58 pm, CBFalconer <> wrote:
    >> Jorge Peixoto wrote:
    >>
    >> > In the answer to question 12.42 of the C FAQ, we have this code:

    >>
    >> > putc((unsigned)((s.i32 >> 24) & 0xff), fp);
    >> > putc((unsigned)((s.i32 >> 16) & 0xff), fp);
    >> > putc((unsigned)((s.i32 >> 8) & 0xff), fp);
    >> > putc((unsigned)(s.i32 & 0xff), fp);

    >>
    >> > putc((s.i16 >> 8) & 0xff, fp);
    >> > putc(s.i16 & 0xff, fp);

    >>
    >> > Why the & 0xff ? The putc function casts its argument to an unsigned
    >> > char, so anything but the 8 lower bits is automatically discarded. And
    >> > the code already assumes the a char is 8 bits.

    >>
    >> Where did you get the magic number 8 there? Bytes and chars can be
    >> any size greater or equal to 8, given by CHAR_BIT in limits.h

    >
    >Yes, but this code (which is from the C FAQ) already assumes that char
    >is 8 bits. Read the answer to the question 12.42 of the FAQ.


    Indeed. And the FAQ explicitly says so ("This code assumes that getc
    reads 8-bit characters").

    --
    jay

    http://c-faq.com/
    http://msdn2.microsoft.com/en-us/express/default.aspx
    http://www.gimpel.com/
    http://www.ubuntu.com/
    http://www.embedded.com/
    jaysome, Oct 27, 2007
    #11
  12. Jorge Peixoto

    CBFalconer Guest

    Jorge Peixoto wrote:
    >

    .... snip ...
    >
    > * Even positive numbers may be represented in a crazy way. On the
    > Deathstation, positive numbers are represented in base 1, that is,
    > the number is the number of 1s in the variable. So 0 is all bits
    > 0, 1 is 1, two is 11, three is 111, etc.


    Not so. The fundamental binary representation of positive integers
    is specified in the standard.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>



    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Oct 27, 2007
    #12
  13. Jorge Peixoto

    Willem Guest

    Jorge wrote:
    ) In the answer to question 12.42 of the C FAQ, we have this code:
    )
    ) putc((unsigned)((s.i32 >> 24) & 0xff), fp);
    ) putc((unsigned)((s.i32 >> 16) & 0xff), fp);
    ) putc((unsigned)((s.i32 >> 8) & 0xff), fp);
    ) putc((unsigned)(s.i32 & 0xff), fp);
    )
    )
    ) putc((s.i16 >> 8) & 0xff, fp);
    ) putc(s.i16 & 0xff, fp);
    )
    ) Why the & 0xff ? The putc function casts its argument to an unsigned
    ) char, so anything but the 8 lower bits is automatically discarded. And
    ) the code already assumes the a char is 8 bits.

    Think about what would happen with this bit of code on a system where
    a char is 9 bits. What would the result be ? What exactly would putc
    be outputting ?


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
    Willem, Oct 27, 2007
    #13
  14. Jorge Peixoto

    James Kuyper Guest

    Willem wrote:
    > Jorge wrote:
    > ) In the answer to question 12.42 of the C FAQ, we have this code:
    > )
    > ) putc((unsigned)((s.i32 >> 24) & 0xff), fp);
    > ) putc((unsigned)((s.i32 >> 16) & 0xff), fp);
    > ) putc((unsigned)((s.i32 >> 8) & 0xff), fp);
    > ) putc((unsigned)(s.i32 & 0xff), fp);
    > )
    > )
    > ) putc((s.i16 >> 8) & 0xff, fp);
    > ) putc(s.i16 & 0xff, fp);
    > )
    > ) Why the & 0xff ? The putc function casts its argument to an unsigned
    > ) char, so anything but the 8 lower bits is automatically discarded. And
    > ) the code already assumes the a char is 8 bits.
    >
    > Think about what would happen with this bit of code on a system where
    > a char is 9 bits. What would the result be ? What exactly would putc
    > be outputting ?


    That char should be assumed to be 8 bits is part of the design
    specifications for this code, so that can't be the justification for the
    &0xff.
    James Kuyper, Oct 27, 2007
    #14
  15. "CBFalconer" <> a écrit dans le message de news:
    ...
    > Jorge Peixoto wrote:
    >> pete <> wrote:
    >>> Jorge Peixoto wrote:
    >>>
    >>>> In the answer to question 12.42 of the C FAQ, we have this code:
    >>>
    >>>> putc((unsigned)((s.i32 >> 24) & 0xff), fp);
    >>>> putc((unsigned)((s.i32 >> 16) & 0xff), fp);
    >>>> putc((unsigned)((s.i32 >> 8) & 0xff), fp);
    >>>> putc((unsigned)(s.i32 & 0xff), fp);
    >>>> putc((s.i16 >> 8) & 0xff, fp);
    >>>> putc(s.i16 & 0xff, fp);
    >>>
    >>>> Why the & 0xff ? The putc function casts its argument to an
    >>>> unsigned char, so anything but the 8 lower bits is automatically
    >>>> discarded. And the code already assumes the a char is 8 bits.
    >>>
    >>> If the representation of negative integers isn't two's complement,
    >>> then converting to unsigned char is different from discarding bits
    >>> when s.i16 is negative.

    >>
    >> It doesn't matter.
    >>
    >> The standard guarantees (according to
    >> http://c-faq.com/decl/inttypes.html)
    >> that an unsigned char can hold any integer from 0 to 255. Since we
    >> are already assuming that char is 8 bits, it can hold at most 256
    >> numbers; there are already 256 numbers between 0 and 255, so 0-255
    >> is exactly the range of numbers that an unsigned char can hold.

    >
    > IMO the fact that the FAQ makes (and documents) assumptions about
    > CHAR_BIT is no excuse for doing the same in this newsgroup,
    > especially without clearly so documenting. In other words, it does
    > matter, and omitting it will lead all sorts of innocent newbies
    > into dingy dark despondent passages. Look with especial suspicion
    > on any constant '8' in your code.


    You are being excessively picky here: the OP writes "the code already
    assumes the char is 8 bits". Innocent newbies should be shielded from these
    arcane considerations until they become proficient enough to master them,
    and versatile enough to actually care about them. Bashing beginners with
    the intricacies of non twos-complement representations is stupid and
    counter-productive. What would you think of a school teacher that would
    concentrate on esoteric typographical details and abtruse considerations on
    ancient hieroglyphs instead of first polishing the basic reading skills of
    her pupils ?

    These constant recriminations are just a form of pedantry, far too common on
    this newsgroup, stretched to the extreme in a form a pointless sickening
    competition.

    --
    Chqrlie
    Charlie Gordon, Oct 27, 2007
    #15
  16. > > * Even positive numbers may be represented in a crazy way. On the
    > > Deathstation, positive numbers are represented in base 1, that is,
    > > the number is the number of 1s in the variable. So 0 is all bits
    > > 0, 1 is 1, two is 11, three is 111, etc.

    >
    > Not so. The fundamental binary representation of positive integers
    > is specified in the standard.


    So a machine that uses BCD would have to do emulation to be the target
    of a C implementation?

    In any event, I think this issue should be in the answer to the
    question. People will be thinking why is that &0xff needed, and the
    FAQ should be didactic.
    Jorge Peixoto, Oct 27, 2007
    #16
  17. "pete" <> a écrit dans le message de news:
    ...
    > Jorge Peixoto wrote:
    >>
    >> On Oct 26, 8:46 pm, pete <> wrote:
    >> > Jorge Peixoto wrote:
    >> >
    >> > > In the answer to question 12.42 of the C FAQ, we have this code:
    >> >
    >> > > putc((unsigned)((s.i32 >> 24) & 0xff), fp);
    >> > > putc((unsigned)((s.i32 >> 16) & 0xff), fp);
    >> > > putc((unsigned)((s.i32 >> 8) & 0xff), fp);
    >> > > putc((unsigned)(s.i32 & 0xff), fp);
    >> >
    >> > > putc((s.i16 >> 8) & 0xff, fp);
    >> > > putc(s.i16 & 0xff, fp);
    >> >
    >> > > Why the & 0xff ? The putc function casts its argument to an unsigned
    >> > > char, so anything but the 8 lower bits is automatically discarded.
    >> > > And
    >> > > the code already assumes the a char is 8 bits.
    >> >
    >> > If the representation of negative integers isn't two's complement,
    >> > then converting to unsigned char
    >> > is different from discarding bits when s.i16 is negative.
    >> >
    >> > --
    >> > pete

    >>
    >> It doesn't matter.
    >>
    >> The standard guarantees (according to
    >> http://c-faq.com/decl/inttypes.html)
    >> that an unsigned char can hold any integer from 0 to 255. Since we are
    >> already assuming that char is 8 bits, it can hold at most 256 numbers;
    >> there are already 256 numbers between 0 and 255, so 0-255 is exactly
    >> the range of numbers that an unsigned char can hold.
    >>
    >> As far as I know (if I am wrong here please correct me), when you
    >> convert from an integer to an unsigned, shorter one, the result is the
    >> nonnegative remander in the division by a number that is 1 bigger
    >> than the maximum number that can be represented by the smaller type.
    >> In our case, this number is 256.
    >> Taking the remainder modulo 256 is equivalent to bitwise and with
    >> 0xff, isn't it?

    >
    > No.
    >
    > There are three allowable ways to represent (-1) in 16 bits:
    > 1111 1111 1111 1111
    > 1111 1111 1111 1110
    > 1000 0000 0000 0001
    >
    > If s.i16 has a value of (-1),
    > then (s.i16 & 0xff) can have a value of either
    > 255, or 254, or 1.
    >
    > ((unsigned char)-1) is always equal to UCHAR_MAX.


    The OP's purpose is to serialize the integer to a stream. For maximum
    portability, it is obviously be preferable that the resulting stream be
    independant of the particular representation of integers on the stream
    writer and reader. Therefore the method used is inappropriate, s.i32 should
    first be converted to an unsigned type, and then shifted around and masked
    off in chunks of fixed numbers of bits (8 is an obvious choice), streamed
    out in a defined order (big endian here).

    putc(((unsigned long)s.i32 >> 24) & 0xff, fp);
    putc(((unsigned long)s.i32 >> 16) & 0xff, fp);
    putc(((unsigned long)s.i32 >> 8) & 0xff, fp);
    putc(((unsigned long)s.i32 >> 0) & 0xff, fp);

    putc(((unsigned int)s.i16 >> 8) & 0xff, fp);
    putc(((unsigned int)s.i16 >> 0) & 0xff, fp);

    This code can be simplified, extra operations are here for reasons of
    symmetry.

    --
    Chqrlie.
    Charlie Gordon, Oct 27, 2007
    #17
  18. Jorge Peixoto

    James Kuyper Guest

    Jorge Peixoto wrote:
    ....
    > So a machine that uses BCD would have to do emulation to be the target
    > of a C implementation?


    Yes. Bitwise operators must be implemented as if operating on a binary
    representation of the value, which would presumably not be a simple
    operation on such a machine. Trinary machines (which have some
    interesting advantages in certain contexts compared to binary machines)
    would also be problematic.
    James Kuyper, Oct 27, 2007
    #18
  19. Jorge Peixoto

    CBFalconer Guest

    Charlie Gordon wrote:
    > "CBFalconer" <> a écrit:
    >

    .... snip ...
    >
    >> IMO the fact that the FAQ makes (and documents) assumptions about
    >> CHAR_BIT is no excuse for doing the same in this newsgroup,
    >> especially without clearly so documenting. In other words, it does
    >> matter, and omitting it will lead all sorts of innocent newbies
    >> into dingy dark despondent passages. Look with especial suspicion
    >> on any constant '8' in your code.

    >
    > You are being excessively picky here: the OP writes "the code
    > already assumes the char is 8 bits". Innocent newbies should be
    > shielded from these arcane considerations until they become
    > proficient enough to master them, and versatile enough to
    > actually care about them. Bashing beginners with the intricacies
    > of non twos-complement representations is stupid and counter-
    > productive. What would you think of a school teacher that would
    > concentrate on esoteric typographical details and abtruse
    > considerations on ancient hieroglyphs instead of first polishing
    > the basic reading skills of her pupils ?
    >
    > These constant recriminations are just a form of pedantry, far too
    > common on this newsgroup, stretched to the extreme in a form a
    > pointless sickening competition.


    You mistake the criticism. It is not about 1's vs 2's complement
    vs sign-magnitude (which is easily handled by dealing with values,
    rather than bit pattern), but about the size of CHAR_BIT,
    specifying the size of a byte on that machine.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>



    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Oct 27, 2007
    #19
  20. Jorge Peixoto

    Chad Guest

    On Oct 26, 4:44 pm, pete <> wrote:
    > Jorge Peixoto wrote:
    >
    > > On Oct 26, 8:46 pm, pete <> wrote:
    > > > Jorge Peixoto wrote:

    >
    > > > > In the answer to question 12.42 of the C FAQ, we have this code:

    >
    > > > > putc((unsigned)((s.i32 >> 24) & 0xff), fp);
    > > > > putc((unsigned)((s.i32 >> 16) & 0xff), fp);
    > > > > putc((unsigned)((s.i32 >> 8) & 0xff), fp);
    > > > > putc((unsigned)(s.i32 & 0xff), fp);

    >
    > > > > putc((s.i16 >> 8) & 0xff, fp);
    > > > > putc(s.i16 & 0xff, fp);

    >
    > > > > Why the & 0xff ? The putc function casts its argument to an unsigned
    > > > > char, so anything but the 8 lower bits is automatically discarded. And
    > > > > the code already assumes the a char is 8 bits.

    >
    > > > If the representation of negative integers isn't two's complement,
    > > > then converting to unsigned char
    > > > is different from discarding bits when s.i16 is negative.

    >
    > > > --
    > > > pete

    >
    > > It doesn't matter.

    >
    > > The standard guarantees (according tohttp://c-faq.com/decl/inttypes.html)
    > > that an unsigned char can hold any integer from 0 to 255. Since we are
    > > already assuming that char is 8 bits, it can hold at most 256 numbers;
    > > there are already 256 numbers between 0 and 255, so 0-255 is exactly
    > > the range of numbers that an unsigned char can hold.

    >
    > > As far as I know (if I am wrong here please correct me), when you
    > > convert from an integer to an unsigned, shorter one, the result is the
    > > nonnegative remander in the division by a number that is 1 bigger
    > > than the maximum number that can be represented by the smaller type.
    > > In our case, this number is 256.
    > > Taking the remainder modulo 256 is equivalent to bitwise and with
    > > 0xff, isn't it?

    >
    > No.
    >
    > There are three allowable ways to represent (-1) in 16 bits:
    > 1111 1111 1111 1111
    > 1111 1111 1111 1110
    > 1000 0000 0000 0001
    >
    > If s.i16 has a value of (-1),
    > then (s.i16 & 0xff) can have a value of either
    > 255, or 254, or 1.
    >
    > ((unsigned char)-1) is always equal to UCHAR_MAX.
    >
    > --
    > pete



    Would 0xff on a 16 bit machine be represented as
    0000 0000 1111 1111

    In other words, would there be leading zero's before 1111 1111 ?
    Chad, Oct 27, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,674
    Smokey Grindel
    Dec 2, 2006
  2. Steve Rainbird

    Check for 0xff in byte array

    Steve Rainbird, Jul 16, 2008, in forum: Java
    Replies:
    6
    Views:
    343
    Steve Rainbird
    Jul 17, 2008
  3. Andrew Stewart

    Discarding putc But Not puts

    Andrew Stewart, Oct 2, 2007, in forum: Ruby
    Replies:
    9
    Views:
    93
    Andrew Stewart
    Oct 3, 2007
  4. Gordon Thiesfeld

    Kernel#putc vs. $stdout#putc

    Gordon Thiesfeld, Feb 20, 2008, in forum: Ruby
    Replies:
    3
    Views:
    97
    Arlen Cuss
    Feb 21, 2008
  5. Minic Minic

    IO#putc writing 2 bytes?

    Minic Minic, May 11, 2008, in forum: Ruby
    Replies:
    11
    Views:
    294
    7stud --
    May 12, 2008
Loading...

Share This Page