conversion

Discussion in 'C Programming' started by Richard Heathfield, Nov 16, 2007.

  1. Roman Mashak said:

    <snip>

    > Compiling it with borland builder results with warning on
    > "pIRV->Val&=~Mask" line: "conversion may loose significant digits". Both
    > operands are (pIRV->Val and Mask) of the same type (UCHAR, which is
    > 'unsigned char'). What's wrong with this snippet?


    Nothing. The "significant digits" that you might lose are insignificant,
    since they are a side-effect of promotion with which you need not concern
    yourself for the purposes of this line of code.

    Let's assume 8-bit bytes, 2-byte ints (because it's less to type).

    We'll assume pIRV->Val has the value 00111101, and Mask has the value
    10101010.

    If you thought ~Mask was 01010101, you'd be forgivably wrong. It's actually
    1111111101010101 (on the system we're assuming). When you & this with
    00111101 (or rather, 0000000000111101) you get 0000000000010101, and you
    then store this in an unsigned char, getting 00010101, which is precisely
    what you want.

    If your system has bigger bytes, bigger ints, or both, then you just get
    more leading 0s to ignore. No big deal.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
    Richard Heathfield, Nov 16, 2007
    #1
    1. Advertising

  2. Roman Mashak said:

    <snip>

    > RH> If you thought ~Mask was 01010101, you'd be forgivably wrong. It's
    > RH> actually
    > RH> 1111111101010101 (on the system we're assuming). When you & this
    > with
    >
    > Does it have something to do with alignment? Why is byte converted to
    > int?


    On (possibly spurious) efficiency grounds.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
    Richard Heathfield, Nov 16, 2007
    #2
    1. Advertising

  3. Roman Mashak said:

    > Hello, Richard!
    > You wrote on Fri, 16 Nov 2007 09:27:51 +0000:
    >
    > RH>>> If you thought ~Mask was 01010101, you'd be forgivably wrong. It's
    > RH>>> actually
    > RH>>> 1111111101010101 (on the system we're assuming). When you & this
    > ??>> with
    > ??>>
    > ??>> Does it have something to do with alignment? Why is byte converted
    > to ??>> int?
    >
    > RH> On (possibly spurious) efficiency grounds.
    > Are these grounds declared by ANSI standard,


    Not in so many words, no, but the Standard does say that "A ``plain'' int
    object has the natural size suggested by the architecture of the execution
    environment". The values of objects of smaller size very often (always?)
    get promoted to this "natural size" during calculations.

    > is this conversion required
    > to be done by every implementation?


    Yes. Look up "integer promotion" and "the usual arithmetic conversions".

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
    Richard Heathfield, Nov 16, 2007
    #3
  4. Richard Heathfield

    Eric Sosman Guest

    Richard Heathfield wrote:
    > Roman Mashak said:
    >
    > <snip>
    >
    >> RH> If you thought ~Mask was 01010101, you'd be forgivably wrong. It's
    >> RH> actually
    >> RH> 1111111101010101 (on the system we're assuming). When you & this
    >> with
    >>
    >> Does it have something to do with alignment? Why is byte converted to
    >> int?

    >
    > On (possibly spurious) efficiency grounds.


    ... for very small values of "possibly." Lots of machines
    that implement C lack the ability to perform arithmetic on
    "narrow" operands like `short x' or `char y' or `int z : 3'.
    Usually, a machine that can't perform three-bit arithmetic
    will instead load the narrow quantity into a wider "register"
    or something of the kind, use its native wide arithmetic to
    operate on the widened operand, and then store part of the
    wide result into a narrow destination. C's "promotions" are
    a recognition of this common implementation practice.

    (It's been almost forty years since I last encountered
    a machine that could do "native" arithmetic on a three-bit
    integer.)

    --
    Eric Sosman
    lid
    Eric Sosman, Nov 16, 2007
    #4
  5. Eric Sosman said:
    > Richard Heathfield wrote:
    >> Roman Mashak said:
    >>
    >>> Why is byte converted to int?

    >>
    >> On (possibly spurious) efficiency grounds.

    >
    > ... for very small values of "possibly."


    32-bit char, anyone? Lots of those around in the embedded world. Promotion
    to int on efficiency grounds is 100% pointless on CSILP32 systems.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
    Richard Heathfield, Nov 16, 2007
    #5
  6. Richard Heathfield

    CBFalconer Guest

    Roman Mashak wrote:
    >
    > typedef struct {
    > UCHAR Num;
    > UCHAR Mask;
    > UCHAR Val;
    > } IRVType, *PIRVType;
    > ...
    > bool SetIRVBit(PIRVType pIRV, UCHAR Num, UCHAR Mask, UCHAR Val)
    > {
    > while (pIRV->Num || pIRV->Mask || pIRV->Val) {
    > if (pIRV->Num!=Num) {
    > pIRV++;
    > continue;
    > }
    > pIRV->Mask|=Mask;
    > pIRV->Val&=~Mask;
    > pIRV->Val|=Val;
    > return TRUE;
    > }
    > return FALSE;
    > }
    >
    > Compiling it with borland builder results with warning on "pIRV->Val&=~Mask"
    > line: "conversion may loose significant digits". Both operands are
    > (pIRV->Val and Mask) of the same type (UCHAR, which is 'unsigned char').
    > What's wrong with this snippet?


    No they're not. One is of the type ~Mask, which is an int.

    In addition, I believe your cavalier action of incrementing the
    pointer pIRV should be flagged as an error. Pointers are not
    integers.

    Thirdly, you are using the type 'bool'. This implies the use of
    C99, and #include <stdbool.h>. This also defines the standard
    values true and false (lower case).

    --
    Chuck F (cbfalconer at maineline dot net)
    <http://cbfalconer.home.att.net>
    Try the download section.



    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Nov 16, 2007
    #6
  7. Richard Heathfield

    Roman Mashak Guest

    Hello,

    typedef struct {
    UCHAR Num;
    UCHAR Mask;
    UCHAR Val;
    } IRVType, *PIRVType;
    ....
    bool SetIRVBit(PIRVType pIRV, UCHAR Num, UCHAR Mask, UCHAR Val)
    {
    while (pIRV->Num || pIRV->Mask || pIRV->Val)
    {
    if (pIRV->Num!=Num)
    {
    pIRV++;
    continue;
    }

    pIRV->Mask|=Mask;
    pIRV->Val&=~Mask;
    pIRV->Val|=Val;
    return TRUE;
    }
    return FALSE;
    }

    Compiling it with borland builder results with warning on "pIRV->Val&=~Mask"
    line: "conversion may loose significant digits". Both operands are
    (pIRV->Val and Mask) of the same type (UCHAR, which is 'unsigned char').
    What's wrong with this snippet?

    Thanks.

    With best regards, Roman Mashak. E-mail:
    Roman Mashak, Nov 17, 2007
    #7
  8. Richard Heathfield

    Roman Mashak Guest

    Hello, Richard!
    You wrote on Fri, 16 Nov 2007 08:12:11 +0000:

    [skip]
    RH> Let's assume 8-bit bytes, 2-byte ints (because it's less to type).

    RH> We'll assume pIRV->Val has the value 00111101, and Mask has the value
    RH> 10101010.

    RH> If you thought ~Mask was 01010101, you'd be forgivably wrong. It's
    RH> actually
    RH> 1111111101010101 (on the system we're assuming). When you & this with

    Does it have something to do with alignment? Why is byte converted to int?

    RH> 00111101 (or rather, 0000000000111101) you get 0000000000010101, and
    RH> you then store this in an unsigned char, getting 00010101, which is
    RH> precisely what you want.

    RH> If your system has bigger bytes, bigger ints, or both, then you just
    RH> get more leading 0s to ignore. No big deal.

    With best regards, Roman Mashak. E-mail:
    Roman Mashak, Nov 17, 2007
    #8
  9. Richard Heathfield

    Roman Mashak Guest

    Hello, Richard!
    You wrote on Fri, 16 Nov 2007 09:27:51 +0000:

    RH>>> If you thought ~Mask was 01010101, you'd be forgivably wrong. It's
    RH>>> actually
    RH>>> 1111111101010101 (on the system we're assuming). When you & this
    ??>> with
    ??>>
    ??>> Does it have something to do with alignment? Why is byte converted to
    ??>> int?

    RH> On (possibly spurious) efficiency grounds.
    Are these grounds declared by ANSI standard, is this conversion required to
    be done by every implementation? Could you tell me more about it or provide
    some links/hints.
    Thanks.

    With best regards, Roman Mashak. E-mail:
    Roman Mashak, Nov 17, 2007
    #9
  10. CBFalconer wrote:
    > Roman Mashak wrote:
    >> typedef struct {
    >> UCHAR Num;
    >> UCHAR Mask;
    >> UCHAR Val;
    >> } IRVType, *PIRVType;
    >> ...
    >> bool SetIRVBit(PIRVType pIRV, UCHAR Num, UCHAR Mask, UCHAR Val)
    >> {
    >> while (pIRV->Num || pIRV->Mask || pIRV->Val) {
    >> if (pIRV->Num!=Num) {
    >> pIRV++;
    >> continue;
    >> }
    >> pIRV->Mask|=Mask;
    >> pIRV->Val&=~Mask;
    >> pIRV->Val|=Val;
    >> return TRUE;
    >> }
    >> return FALSE;
    >> }
    >>
    >> Compiling it with borland builder results with warning on "pIRV->Val&=~Mask"
    >> line: "conversion may loose significant digits". Both operands are
    >> (pIRV->Val and Mask) of the same type (UCHAR, which is 'unsigned char').
    >> What's wrong with this snippet?

    >
    > No they're not. One is of the type ~Mask, which is an int.


    You mean it's of the type *of* ~Mask.

    > In addition, I believe your cavalier action of incrementing the
    > pointer pIRV should be flagged as an error. Pointers are not
    > integers.


    No, they certainly aren't, but incrementing a pointer is well defined.

    > Thirdly, you are using the type 'bool'. This implies the use of
    > C99, and #include <stdbool.h>. This also defines the standard
    > values true and false (lower case).


    No, it doesn't imply the use of C99. "bool" is a valid identifier in
    C90. For that matter, "bool" is a valid identifier in C99, particularly
    if there's no "#include <stdbool.h>". Probably the type "bool" and
    the identifiers (macros?) "FALSE" and "TRUE" are defined elsewhere. (It
    would have been nice to see those declarations, and the declaration of
    UCHAR.)

    --
    Keith Thompson (The_Other_Keith) <>
    Looking for software development work in the San Diego area.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Nov 18, 2007
    #10
  11. Roman Mashak wrote:
    > Hello, Keith!
    > You wrote on Sun, 18 Nov 2007 00:06:12 -0800:
    >
    > ??>> Thirdly, you are using the type 'bool'. This implies the use of
    > ??>> C99, and #include <stdbool.h>. This also defines the standard
    > ??>> values true and false (lower case).
    >
    > KT> No, it doesn't imply the use of C99. "bool" is a valid identifier in
    > KT> C90. For that matter, "bool" is a valid identifier in C99,
    > KT> particularly if there's no "#include <stdbool.h>". Probably the type
    > I could not find stdbool.h neither in debian/linux nor in cygwin
    > environments.


    It's on my Cygwin system (with gcc 3.4.4). Perhaps you need to update
    your system. (stdbool.h is provided by gcc, not as part of the C library.)

    My Ubuntu 7.10 system (based on Debian) also has it (gcc 4.1.3).

    But the only really topical thing to be said is that <stdbool.h> is
    required for any conforming C99 implementation, but is optional for any
    implementation that doesn't claim to conform to C99.

    --
    Keith Thompson (The_Other_Keith) <>
    Looking for software development work in the San Diego area.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Nov 19, 2007
    #11
  12. Richard Heathfield

    Roman Mashak Guest

    Hello, Keith!
    You wrote on Sun, 18 Nov 2007 00:06:12 -0800:

    ??>> Thirdly, you are using the type 'bool'. This implies the use of
    ??>> C99, and #include <stdbool.h>. This also defines the standard
    ??>> values true and false (lower case).

    KT> No, it doesn't imply the use of C99. "bool" is a valid identifier in
    KT> C90. For that matter, "bool" is a valid identifier in C99,
    KT> particularly if there's no "#include <stdbool.h>". Probably the type
    I could not find stdbool.h neither in debian/linux nor in cygwin
    environments.

    With best regards, Roman Mashak. E-mail:
    Roman Mashak, Nov 19, 2007
    #12
  13. Richard Heathfield

    CBFalconer Guest

    Roman Mashak wrote:
    > Keith Thompson wrote:
    >> Charles Falconer wrote:
    >>
    >>> Thirdly, you are using the type 'bool'. This implies the use of
    >>> C99, and #include <stdbool.h>. This also defines the standard
    >>> values true and false (lower case).

    >
    >> No, it doesn't imply the use of C99. "bool" is a valid identifier
    >> in C90. For that matter, "bool" is a valid identifier in C99,
    >> particularly if there's no "#include <stdbool.h>". Probably the

    >
    > I could not find stdbool.h neither in debian/linux nor in cygwin
    > environments.


    Please don't strip attributions. I added some back in.

    stdbool.h only exists for C99 implementations. Yes, you can use
    bool in C90 (and C99 when no stdbool.h is included), but such use
    requires definition. There was no such definition in the
    originally quoted code (nor any possible #include). To have
    stdbool.h available you must at least (if using gcc) use "-std=c99"
    in place of "ansi". Then it depends on your installation.

    --
    Chuck F (cbfalconer at maineline dot net)
    <http://cbfalconer.home.att.net>
    Try the download section.



    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Nov 20, 2007
    #13
  14. CBFalconer wrote:
    > Roman Mashak wrote:
    >> Keith Thompson wrote:
    >>> Charles Falconer wrote:
    >>>
    >>>> Thirdly, you are using the type 'bool'. This implies the use of
    >>>> C99, and #include <stdbool.h>. This also defines the standard
    >>>> values true and false (lower case).
    >>> No, it doesn't imply the use of C99. "bool" is a valid identifier
    >>> in C90. For that matter, "bool" is a valid identifier in C99,
    >>> particularly if there's no "#include <stdbool.h>". Probably the

    >> I could not find stdbool.h neither in debian/linux nor in cygwin
    >> environments.

    >
    > Please don't strip attributions. I added some back in.
    >
    > stdbool.h only exists for C99 implementations. Yes, you can use
    > bool in C90 (and C99 when no stdbool.h is included), but such use
    > requires definition. There was no such definition in the
    > originally quoted code (nor any possible #include). To have
    > stdbool.h available you must at least (if using gcc) use "-std=c99"
    > in place of "ansi". Then it depends on your installation.


    In C90, <stdbool.h> is not a standard header; therefore a C90 compiler
    is allowed to provide it, as well as the _Bool keyword, as an extension.
    (In fact, "gcc -std=c89" does so.)

    The originally quoted code used at least one other identifier whose
    definition was not shown.

    --
    Keith Thompson (The_Other_Keith) <>
    Looking for software development work in the San Diego area.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Nov 20, 2007
    #14
    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. Luc Bisson

    Framework 1.0 to 1.1 conversion

    Luc Bisson, Nov 4, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    595
    Jim Blizzard [MSFT]
    Nov 19, 2003
  2. Amka
    Replies:
    8
    Views:
    522
    Jay B. Harlow [MVP - Outlook]
    Jan 28, 2004
  3. Thomas Bartzick
    Replies:
    0
    Views:
    2,258
    Thomas Bartzick
    Jun 26, 2003
  4. Troels Smit

    Conversion 1QN -> 2'Complement

    Troels Smit, Jun 30, 2003, in forum: VHDL
    Replies:
    1
    Views:
    4,149
    Troels Smit
    Jul 1, 2003
  5. , India
    Replies:
    2
    Views:
    448
    Fraser Ross
    Sep 15, 2009
Loading...

Share This Page