BItwise Operation ...

Discussion in 'C Programming' started by loudking, Oct 30, 2007.

  1. loudking

    loudking Guest

    Hello, all.

    I am not good at bitwise operation, so I wonder if some experts could
    do me a help.

    In a.c, somebody defined
    ================================================
    # define u_int64 unsigned long long
    # define u_short unsigned short
    # define u_int unsigned int

    u_short txid_slt;
    u_int txid_sqn;

    u_int64 tx_id= ((u_int64)txid_slt << 32) | (u_int64)txid_sqn;

    Later, in b.c, I have to reassemble tx_id into "slt" and "sqn".
    =================================================
    struct redo_xid {
    u_int sqn;
    u_short slot;
    };

    Can I use the following expression to achieve this goal?
    ==================================================
    struct redo_xid xid = (struct redo_xid)tx_id;

    Many many thanks!
     
    loudking, Oct 30, 2007
    #1
    1. Advertising

  2. On 30 Oct, 09:49, loudking <> wrote:

    > I am not good at bitwise operation,


    they aren't that complicated...


    > so I wonder if some experts could
    > do me a help.
    >
    > In a.c, somebody defined
    > ================================================
    > # define u_int64 unsigned long long


    long long doesn't have to be 64-bits


    > # define u_short unsigned short
    > # define u_int unsigned int


    you appear to be assuming int is 32 bits. It doesn't have to be.
    I generally don't like typedefs like this.


    > u_short txid_slt;
    > u_int txid_sqn;
    >
    > u_int64 tx_id= ((u_int64)txid_slt << 32) | (u_int64)txid_sqn;


    I wouldn't bother with the casts.

    u_int64 tx_id = (txid_slt << 32) | txid_sqn;


    > Later, in b.c, I have to reassemble tx_id into "slt" and "sqn".
    > =================================================
    > struct redo_xid {
    > u_int sqn;
    > u_short slot;
    >
    > };
    >
    > Can I use the following expression to achieve this goal?
    > ==================================================
    > struct redo_xid xid = (struct redo_xid)tx_id;


    why not reverse the previous step?

    struct redo_xid xid;

    xid.sqn = tx_id & 0xffffffff; /* 32 1s */
    xid.slot = (tx_id >> 32) & 0xffff;


    --
    Nick Keighley

    Casting is almost always wrong,
    and the places where it's right are rarely the places you'd guess.
    Richard Heathfield
     
    Nick Keighley, Oct 30, 2007
    #2
    1. Advertising

  3. loudking

    loudking Guest

    > why not reverse the previous step?
    >
    > struct redo_xid xid;
    >
    > xid.sqn = tx_id & 0xffffffff; /* 32 1s */
    > xid.slot = (tx_id >> 32) & 0xffff;
    >
    > --


    Thanks!
     
    loudking, Oct 30, 2007
    #3
  4. loudking

    Martin Wells Guest

    loudking:

    > # define u_int64 unsigned long long
    > # define u_short unsigned short
    > # define u_int unsigned int



    C has typedef for a reason:

    typedef long long unsigned u_int64;
    typedef short unsigned u_short;
    typedef unsigned u_int;

    The syntax for typedef is the same for defining a variable:

    int (*x)[7]; /* x is a variable */
    typedef int (*x)[7]; /* x is a type */


    You'll notice the difference when you try:

    typedef int *Type1;
    #define Type2 int*

    int main(void)
    {
    const Type1 a;
    const Type2 b;

    b = 0;

    return 0;
    }



    > u_short txid_slt;
    > u_int txid_sqn;
    >
    > u_int64 tx_id= ((u_int64)txid_slt << 32) | (u_int64)txid_sqn;
    >
    > Later, in b.c, I have to reassemble tx_id into "slt" and "sqn".
    > =================================================
    > struct redo_xid {
    > u_int sqn;
    > u_short slot;
    >
    > };
    >
    > Can I use the following expression to achieve this goal?
    > ==================================================
    > struct redo_xid xid = (struct redo_xid)tx_id;



    None of the C Standards say that you can... in fact they explicitly
    allow an implementation to explode in your face if you try. As for
    *your own* platform... who knows...

    Martin
     
    Martin Wells, Oct 30, 2007
    #4
  5. loudking

    James Kuyper Guest

    Nick Keighley wrote:
    > On 30 Oct, 09:49, loudking <> wrote:
    >
    >> I am not good at bitwise operation,

    >
    > they aren't that complicated...
    >
    >
    >> so I wonder if some experts could
    >> do me a help.
    >>
    >> In a.c, somebody defined
    >> ================================================
    >> # define u_int64 unsigned long long

    >
    > long long doesn't have to be 64-bits
    >
    >
    >> # define u_short unsigned short
    >> # define u_int unsigned int

    >
    > you appear to be assuming int is 32 bits. It doesn't have to be.
    > I generally don't like typedefs like this.


    Actually, the code below does imply that assumption, it could also be
    the case that u_int is either larger or smaller than 32 bits, but that
    every value that actually needs to be stored in a 'u_int' type fits in
    32 bits, or an unsigned int, whichever is smaller. That makes this code
    non-portable, but making it portable would require knowing exactly what
    the valid range of the following two variables is, which we don't know:

    >> u_short txid_slt;
    >> u_int txid_sqn;
    >>
    >> u_int64 tx_id= ((u_int64)txid_slt << 32) | (u_int64)txid_sqn;

    >
    > I wouldn't bother with the casts.
    >
    > u_int64 tx_id = (txid_slt << 32) | txid_sqn;


    Without the first cast, txid_slt would be promoted to 'int', unless
    USHRT_MAX > INT_MAX, in which case it would be promoted to 'unsigned int'.

    If it gets promoted to 'int', then the left shift has undefined behavior
    unless

    INT_MAX >= (u_int64)USHRT_MAX << 32

    If it gets converted to 'unsigned int', the left shift will have defined
    behavior, but that defined behavior involves multiplying by 2^32, and
    then reducing the result modulo UINT_MAX+1, which will discard
    high-order bits unless

    UINT_MAX >= (u_int64)USHRT_MAX << 32

    See 6.5.7p4 for details.

    However, I agree that the second cast is unnecessary - it will happen
    automatically as a side effect of the first cast.

    >> Later, in b.c, I have to reassemble tx_id into "slt" and "sqn".
    >> =================================================
    >> struct redo_xid {
    >> u_int sqn;
    >> u_short slot;
    >>
    >> };
    >>
    >> Can I use the following expression to achieve this goal?
    >> ==================================================
    >> struct redo_xid xid = (struct redo_xid)tx_id;


    No - there is no such conversion.

    > why not reverse the previous step?
    >
    > struct redo_xid xid;
    >
    > xid.sqn = tx_id & 0xffffffff; /* 32 1s */
    > xid.slot = (tx_id >> 32) & 0xffff;


    The mask in is unnecessary for the calculation of xid.slot. It may
    actually discard data if unsigned_short is larger than 32 bits (which is
    unlikely, especially for this code, but it would be possible).
     
    James Kuyper, Oct 30, 2007
    #5
  6. Martin Wells <> writes:
    > loudking:
    >> # define u_int64 unsigned long long
    >> # define u_short unsigned short
    >> # define u_int unsigned int

    >
    > C has typedef for a reason:
    >
    > typedef long long unsigned u_int64;
    > typedef short unsigned u_short;
    > typedef unsigned u_int;

    [...]

    Agreed. C also has "unsigned short" and "unsigned int" for a reason.
    Just refer to "unsigned short" and "unsigned int" directly. The
    aliases "u_short" and "u_int" add nothing useful; they just make me
    wonder why you bothered to define new names for types that already
    have perfectly good names -- or, worse, whether you've defined
    "u_short" as something other than "unsigned short".

    As for u_int64, unsigned long long is required to be *at least* 64
    bits, but it's allowed to be wider.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 30, 2007
    #6
    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. Pasquale Imbemba

    Bitwise Operation

    Pasquale Imbemba, May 6, 2004, in forum: Java
    Replies:
    2
    Views:
    548
    Roedy Green
    May 7, 2004
  2. biswaranjan.rath

    bitwise AND operation in xslt

    biswaranjan.rath, May 8, 2006, in forum: XML
    Replies:
    3
    Views:
    4,901
    shaunroe
    Nov 12, 2008
  3. Patrick Hoonhout

    bitwise operation...

    Patrick Hoonhout, Aug 27, 2003, in forum: C Programming
    Replies:
    13
    Views:
    668
    Alan Balmer
    Aug 28, 2003
  4. Magix

    Bitwise operation

    Magix, Jul 30, 2004, in forum: C Programming
    Replies:
    6
    Views:
    737
    Joe Wright
    Jul 31, 2004
  5. Magix

    Bitwise Operation

    Magix, Oct 15, 2004, in forum: C Programming
    Replies:
    5
    Views:
    557
    Dimension
    Oct 15, 2004
Loading...

Share This Page