swapping bytes in an integer

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • john@fcs.uga.edu

    #16
    Re: swapping bytes in an integer

    EventHelix.com wrote:[color=blue][color=green]
    > > If I have a 32 bit unsigned int that is in the wrong byte order, how
    > > can I convert it? For example, if have a number 0x090a0b0c how can I
    > > reverse this to 0x0c0b0a09 ?[/color]
    >
    > The following article should help:
    > http://www.eventhelix.com/RealtimeMa...ndOrdering.htm
    >
    > --
    > EventStudio System Designer 2.5 - http://www.EventHelix.com/EventStudio
    > Sequence Diagram Based System Design and Object Interaction Modeling
    > Tool[/color]
    [color=blue]
    >From this web site...[/color]

    Routines to convert between big-endian and little-endian formats are
    actually quite straight forward. The routines shown below will convert
    from both ways, i.e. big-endian to little-endian and back.
    Big-endian to Little-endian conversion and back


    short convert_short(s hort in)
    {
    short out;
    char *p_in = (char *) ∈
    char *p_out = (char *) &out;
    p_out[0] = p_in[1];
    p_out[1] = p_in[0];
    return out;
    }

    long convert_long(lo ng in)
    {
    long out;
    char *p_in = (char *) ∈
    char *p_out = (char *) &out;
    p_out[0] = p_in[3];
    p_out[1] = p_in[2];
    p_out[2] = p_in[1];
    p_out[3] = p_in[0];
    return out;
    }

    Comment

    • Rod Pemberton

      #17
      Re: swapping bytes in an integer


      <john@fcs.uga.e du> wrote in message
      news:1147122187 .958124.59280@i 40g2000cwc.goog legroups.com...[color=blue]
      > If I have a 32 bit unsigned int that is in the wrong byte order, how
      > can I convert it? For example, if have a number 0x090a0b0c how can I
      > reverse this to 0x0c0b0a09 ?
      >[/color]

      It seems you've found ntohl(), but this is how:

      unsigned long a,b;

      a=0x090a0b0c;
      b=((a&0xFF00000 0)>>24)|((a&0x0 0FF0000)>>8)|(( a&0x0000FF00)<< 8)|((a&0x000000 F
      F)<<24);

      Of course, you can drop any place holder zeros between 0x and FF.


      Rod Pemberton


      Comment

      • Eric Sosman

        #18
        Re: swapping bytes in an integer



        john@fcs.uga.ed u wrote On 05/08/06 18:18,:[color=blue]
        > Ian Collins wrote:
        >[color=green]
        >>john@fcs.uga. edu wrote:
        >>[color=darkred]
        >>>If I have a 32 bit unsigned int that is in the wrong byte order, how
        >>>can I convert it? For example, if have a number 0x090a0b0c how can I
        >>>reverse this to 0x0c0b0a09 ?
        >>>[/color]
        >>
        >>It my be non-standard, bit if you system has the networking library
        >>function ntohl and you don't require portability, you can use that.
        >>
        >>--
        >>Ian Collins.[/color]
        >
        >
        > I just tried ntohl() in my program and this works perfectly. I think I
        > will use this method. I want to thank everyone who replied for all of
        > their great ideas! This help is greatly appreciated.[/color]

        <off-topic reason="potenti al bug">

        Be careful: ntohl() does *not* do what you asked.
        It converts "network byte order" (Big-Endian) to "host
        byte order" (whatever your machine uses). If your
        machine uses Big-Endian byte order already, ntohl()
        will not swap the bytes: it will do nothing at all.
        To put it another way, ntohl() may in fact do what you
        want on the machine you're using at the moment, but
        will definitely *not* do what you want on all machines.

        If you need to swap the bytes unconditionally , no
        matter what machine you're using, you'll have to work
        a little harder.

        </off-topic>

        --
        Eric.Sosman@sun .com

        Comment

        • john@fcs.uga.edu

          #19
          Re: swapping bytes in an integer

          Wow! This code is really awesome. I think this is the absolute best
          way I have seen yet. I will have to study your code and break it down
          to see how it works exaclty. Do you think that it could it be placed
          within a #define ?

          Thanks,
          -John

          Comment

          • Keith Thompson

            #20
            Re: swapping bytes in an integer

            Eric Sosman <Eric.Sosman@su n.com> writes:[color=blue]
            > john@fcs.uga.ed u wrote On 05/08/06 18:18,:[color=green]
            >> Ian Collins wrote:[color=darkred]
            >>>john@fcs.uga .edu wrote:
            >>>>If I have a 32 bit unsigned int that is in the wrong byte order, how
            >>>>can I convert it? For example, if have a number 0x090a0b0c how can I
            >>>>reverse this to 0x0c0b0a09 ?
            >>>
            >>>It my be non-standard, bit if you system has the networking library
            >>>function ntohl and you don't require portability, you can use that.[/color]
            >>
            >> I just tried ntohl() in my program and this works perfectly. I think I
            >> will use this method. I want to thank everyone who replied for all of
            >> their great ideas! This help is greatly appreciated.[/color]
            >
            > <off-topic reason="potenti al bug">
            >
            > Be careful: ntohl() does *not* do what you asked.
            > It converts "network byte order" (Big-Endian) to "host
            > byte order" (whatever your machine uses). If your
            > machine uses Big-Endian byte order already, ntohl()
            > will not swap the bytes: it will do nothing at all.
            > To put it another way, ntohl() may in fact do what you
            > want on the machine you're using at the moment, but
            > will definitely *not* do what you want on all machines.
            >
            > If you need to swap the bytes unconditionally , no
            > matter what machine you're using, you'll have to work
            > a little harder.[/color]

            We're not certain exactly what the OP's requirements are, only what he
            stated them to be. He might need a general solution to swapping bytes
            (in which case ntohl() won't do it), or it may be that the only time
            he'll see a number in the wrong byte order is when it comes from a
            network (in which case ntohl() is probably just the thing).
            [color=blue]
            > </off-topic>[/color]

            --
            Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

            Comment

            • Rod Pemberton

              #21
              Re: swapping bytes in an integer


              <john@fcs.uga.e du> wrote in message
              news:1147190006 .296430.123170@ j33g2000cwa.goo glegroups.com.. .[color=blue]
              > Wow! This code is really awesome. I think this is the absolute best
              > way I have seen yet. I will have to study your code and break it down
              > to see how it works exaclty. Do you think that it could it be placed
              > within a #define ?
              >[/color]

              Yes. Just remember that it's only for 'unsigned long' 's which are 32-bits
              in length (i.e., rarely it's non-portable). You'd need a different version
              for other unsigned types: short, long long, etc. This method won't work
              with signed types.

              /* BS for byte-swap */
              #define BS(a)
              (((a)&0xFF00000 0)>>24)|(((a)&0 xFF0000)>>8)|(( (a)&0xFF00)<<8) |(((a)&0xFF)<<2 4
              )

              /*...*/
              unsigned long a,b;

              a=0x090a0b0c;
              b=BS(a);


              Each 'FF' masks off one of the four respective bytes using the '&' bitwise
              and operator. This leaves you with four unsigned long each of which has a
              byte to be relocated. The '>>' and '<<' bitshift operators move each byte
              to it's new position (within an 'unsigned long'). The '|' bitwise or
              operator puts all four unsigned long's, each one with one relocated byte,
              back together.

              1) four unsigned long's (each 'a')
              0x090a0b0
              0x090a0b0
              0x090a0b0
              0x090a0b0

              2) and masking, four bytes within unsigned longs
              0x09000000
              0x000a0000
              0x00000b00
              0x0000000c

              3) shifting, relocated byte within unsigned longs
              0x00000009
              0x00000a00
              0x000b0000
              0x0c000000

              4) or four together
              0x0c0b0a09


              This actually optimizes very well with most modern compilers.

              It also avoids using byte swapping constructs like arrays or unions which
              (in my experience) can cause other programming headaches.


              Rod Pemberton


              Comment

              • Robert Latest

                #22
                Re: swapping bytes in an integer

                On 9 May 2006 08:53:26 -0700,
                john@fcs.uga.ed u <john@fcs.uga.e du> wrote
                in Msg. <1147190006.296 430.123170@j33g 2000cwa.googleg roups.com>[color=blue]
                > Wow! This code is really awesome. I think this is the absolute best
                > way I have seen yet. I will have to study your code and break it down
                > to see how it works exaclty.[/color]

                It looks confusing at first, but is simple in reality.
                [color=blue]
                > Do you think that it could it be placed
                > within a #define ?[/color]

                It could be, but the argument is evaluated four times which will create
                trouble if it has side effects. If your macros is called BYTESWAP(a),
                then

                BYTESWAP(++a) will invoke undefine behavior, and
                BYTESWAP(some_f unc(x)) will invoke some_func four times.

                Better implement it as an (inline) function.

                robert

                Comment

                • Keith Thompson

                  #23
                  Re: swapping bytes in an integer

                  "Rod Pemberton" <do_not_have@bi tfoad.cmm> writes:[color=blue]
                  > <john@fcs.uga.e du> wrote in message
                  > news:1147190006 .296430.123170@ j33g2000cwa.goo glegroups.com.. .[color=green]
                  >> Wow! This code is really awesome. I think this is the absolute best
                  >> way I have seen yet. I will have to study your code and break it down
                  >> to see how it works exaclty. Do you think that it could it be placed
                  >> within a #define ?
                  >>[/color]
                  >
                  > Yes. Just remember that it's only for 'unsigned long' 's which are 32-bits
                  > in length (i.e., rarely it's non-portable). You'd need a different version
                  > for other unsigned types: short, long long, etc. This method won't work
                  > with signed types.[/color]

                  I think what he means by "rarely it's non-portable" is "it's
                  non-portable". unsigned long isn't necessary 32 bits; I regularly use
                  systems on which it's 64 bits.

                  --
                  Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

                  Comment

                  • Rod Pemberton

                    #24
                    Re: swapping bytes in an integer


                    "Keith Thompson" <kst-u@mib.org> wrote in message
                    news:ln64kdnasi .fsf@nuthaus.mi b.org...[color=blue]
                    > "Rod Pemberton" <do_not_have@bi tfoad.cmm> writes:[color=green]
                    > > <john@fcs.uga.e du> wrote in message
                    > > news:1147190006 .296430.123170@ j33g2000cwa.goo glegroups.com.. .[color=darkred]
                    > >> Wow! This code is really awesome. I think this is the absolute best
                    > >> way I have seen yet. I will have to study your code and break it down
                    > >> to see how it works exaclty. Do you think that it could it be placed
                    > >> within a #define ?
                    > >>[/color]
                    > >
                    > > Yes. Just remember that it's only for 'unsigned long' 's which are[/color][/color]
                    32-bits[color=blue][color=green]
                    > > in length (i.e., rarely it's non-portable). You'd need a different[/color][/color]
                    version[color=blue][color=green]
                    > > for other unsigned types: short, long long, etc. This method won't work
                    > > with signed types.[/color]
                    >
                    > I think what he means by "rarely it's non-portable" is "it's
                    > non-portable". unsigned long isn't necessary 32 bits; I regularly use
                    > systems on which it's 64 bits.
                    >[/color]

                    Just because you use a system regularly doesn't mean that it's a non-rare
                    system. I wouldn't exactly call the Sun-Blade-100's or Cray's you've used
                    common... In fact, I wouldn't call any mainframe or mini-frame (including
                    the ones I've used) common.


                    Rod Pemberton


                    Comment

                    • Ian Collins

                      #25
                      Re: swapping bytes in an integer

                      Rod Pemberton wrote:[color=blue]
                      > "Keith Thompson" <kst-u@mib.org> wrote in message
                      > news:ln64kdnasi .fsf@nuthaus.mi b.org...
                      >[color=green]
                      >>"Rod Pemberton" <do_not_have@bi tfoad.cmm> writes:
                      >>[color=darkred]
                      >>><john@fcs.ug a.edu> wrote in message
                      >>>news:1147190 006.296430.1231 70@j33g2000cwa. googlegroups.co m...
                      >>>
                      >>>>Wow! This code is really awesome. I think this is the absolute best
                      >>>>way I have seen yet. I will have to study your code and break it down
                      >>>>to see how it works exaclty. Do you think that it could it be placed
                      >>>>within a #define ?
                      >>>>
                      >>>
                      >>>Yes. Just remember that it's only for 'unsigned long' 's which are[/color][/color]
                      >
                      > 32-bits
                      >[color=green][color=darkred]
                      >>>in length (i.e., rarely it's non-portable). You'd need a different[/color][/color]
                      >
                      > version
                      >[color=green][color=darkred]
                      >>>for other unsigned types: short, long long, etc. This method won't work
                      >>>with signed types.[/color]
                      >>
                      >>I think what he means by "rarely it's non-portable" is "it's
                      >>non-portable". unsigned long isn't necessary 32 bits; I regularly use
                      >>systems on which it's 64 bits.
                      >>[/color]
                      >
                      >
                      > Just because you use a system regularly doesn't mean that it's a non-rare
                      > system. I wouldn't exactly call the Sun-Blade-100's or Cray's you've used
                      > common... In fact, I wouldn't call any mainframe or mini-frame (including
                      > the ones I've used) common.
                      >[/color]
                      There are a lot of AMD64 and Intel 64 bit systems out here.

                      --
                      Ian Collins.

                      Comment

                      • Keith Thompson

                        #26
                        Re: swapping bytes in an integer

                        "Rod Pemberton" <do_not_have@bi tfoad.cmm> writes:[color=blue]
                        > "Keith Thompson" <kst-u@mib.org> wrote in message
                        > news:ln64kdnasi .fsf@nuthaus.mi b.org...[color=green]
                        >> "Rod Pemberton" <do_not_have@bi tfoad.cmm> writes:[color=darkred]
                        >> > <john@fcs.uga.e du> wrote in message
                        >> > news:1147190006 .296430.123170@ j33g2000cwa.goo glegroups.com.. .
                        >> >> Wow! This code is really awesome. I think this is the absolute best
                        >> >> way I have seen yet. I will have to study your code and break it down
                        >> >> to see how it works exaclty. Do you think that it could it be placed
                        >> >> within a #define ?
                        >> >>
                        >> >
                        >> > Yes. Just remember that it's only for 'unsigned long' 's which
                        >> > are 32-bits in length (i.e., rarely it's non-portable). You'd
                        >> > need a different version for other unsigned types: short, long
                        >> > long, etc. This method won't work with signed types.[/color]
                        >>
                        >> I think what he means by "rarely it's non-portable" is "it's
                        >> non-portable". unsigned long isn't necessary 32 bits; I regularly use
                        >> systems on which it's 64 bits.[/color]
                        >
                        > Just because you use a system regularly doesn't mean that it's a non-rare
                        > system. I wouldn't exactly call the Sun-Blade-100's or Cray's you've used
                        > common... In fact, I wouldn't call any mainframe or mini-frame (including
                        > the ones I've used) common.[/color]

                        I didn't say they're non-rare; that's not the point. The point is
                        that saying "rarely it's non-portable" merely obfuscates the fact that
                        it's *non-portable*.

                        64-bit systems are already showing up as home PCs for everyday use,
                        and they're becoming more and more common.

                        If you write code that works only on 32-bit systems, it's likely to
                        work on *most* modern systems. But why waste your time writing code
                        that works on most systems, when you can write *portable* code with
                        little additional effort?

                        All the world was not a VAX 25 years ago, and all the world is not a
                        32-bit x86 today.

                        --
                        Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

                        Comment

                        • Rod Pemberton

                          #27
                          Re: swapping bytes in an integer


                          "Keith Thompson" <kst-u@mib.org> wrote in message
                          news:lnfyjhll6f .fsf@nuthaus.mi b.org...[color=blue]
                          > "Rod Pemberton" <do_not_have@bi tfoad.cmm> writes:[color=green]
                          > > "Keith Thompson" <kst-u@mib.org> wrote in message
                          > > news:ln64kdnasi .fsf@nuthaus.mi b.org...[color=darkred]
                          > >> "Rod Pemberton" <do_not_have@bi tfoad.cmm> writes:
                          > >> > <john@fcs.uga.e du> wrote in message
                          > >> > news:1147190006 .296430.123170@ j33g2000cwa.goo glegroups.com.. .
                          > >> >> Wow! This code is really awesome. I think this is the absolute best
                          > >> >> way I have seen yet. I will have to study your code and break it[/color][/color][/color]
                          down[color=blue][color=green][color=darkred]
                          > >> >> to see how it works exaclty. Do you think that it could it be[/color][/color][/color]
                          placed[color=blue][color=green][color=darkred]
                          > >> >> within a #define ?
                          > >> >>
                          > >> >
                          > >> > Yes. Just remember that it's only for 'unsigned long' 's which
                          > >> > are 32-bits in length (i.e., rarely it's non-portable). You'd
                          > >> > need a different version for other unsigned types: short, long
                          > >> > long, etc. This method won't work with signed types.
                          > >>
                          > >> I think what he means by "rarely it's non-portable" is "it's
                          > >> non-portable". unsigned long isn't necessary 32 bits; I regularly use
                          > >> systems on which it's 64 bits.[/color]
                          > >
                          > > Just because you use a system regularly doesn't mean that it's a[/color][/color]
                          non-rare[color=blue][color=green]
                          > > system. I wouldn't exactly call the Sun-Blade-100's or Cray's you've[/color][/color]
                          used[color=blue][color=green]
                          > > common... In fact, I wouldn't call any mainframe or mini-frame[/color][/color]
                          (including[color=blue][color=green]
                          > > the ones I've used) common.[/color]
                          >
                          > I didn't say they're non-rare; that's not the point. The point is
                          > that saying "rarely it's non-portable" merely obfuscates the fact that
                          > it's *non-portable*.
                          >[/color]

                          Your perspective is what's incorrect. It is portable. It's portable to any
                          machine which uses 32-bits for 'unsigned long' which is the extreme majority
                          of architectures in existence. It's _rare_ for an 'unsigned long' to be any
                          other size even on 16-bit or 64-bit machines. You've attempted to redefine
                          portability in terms of a few obscure machines.
                          [color=blue]
                          > 64-bit systems are already showing up as home PCs for everyday use,
                          > and they're becoming more and more common.
                          >
                          > If you write code that works only on 32-bit systems, it's likely to
                          > work on *most* modern systems. But why waste your time writing code
                          > that works on most systems, when you can write *portable* code with
                          > little additional effort?
                          >[/color]

                          Since you (claim to) have experience in this area, feel free to post a
                          portable solution. But, that would violate your personal no-code policy
                          wouldn't it?


                          Rod Pemberton


                          Comment

                          • David Resnick

                            #28
                            Re: swapping bytes in an integer


                            Rod Pemberton wrote:[color=blue]
                            > "Keith Thompson" <kst-u@mib.org> wrote in message[color=green]
                            > > I didn't say they're non-rare; that's not the point. The point is
                            > > that saying "rarely it's non-portable" merely obfuscates the fact that
                            > > it's *non-portable*.
                            > >[/color]
                            >
                            > Your perspective is what's incorrect. It is portable. It's portable to any
                            > machine which uses 32-bits for 'unsigned long' which is the extreme majority
                            > of architectures in existence. It's _rare_ for an 'unsigned long' to be any
                            > other size even on 16-bit or 64-bit machines. You've attempted to redefine
                            > portability in terms of a few obscure machines.
                            >[/color]

                            I think this discussion is overblown. On the one hand, the O/P
                            specified 32 bit unsigned ints, and the solution you provided is OK
                            given that spec seems to me. It could add an assert(sizeof(i nt)==4 &&
                            CHAR_BITS==8) to make sure it isn't misused, but whatever.

                            On the other hand, the fact that many (at least non-embedded) machines
                            now use 32 bit ints/longs is not to me relevant. I'd be surprised if
                            most new desktop/server machines were not 64 bit in the relatively near
                            future. Writing code, wherever possible, to not care seems entirely
                            reasonable, unless one is trying to ensure future programming work
                            upgrading ones source code to be "64 bit safe". This is quite
                            different (IMHO) than the arguments about whether assuming NULL is all
                            bits 0 is OK based on the fact that it wasn't in some obsolescent
                            architectures. I'd go with the pedanticly correct side there too, but
                            I think it is relatively unlikely that someone will make a new machine
                            that doesn't treat all bits 0 as NULL. It is a certainty that many new
                            machines will be released where compilers use long ints that are 64
                            bits...

                            -David

                            Comment

                            • Jordan Abel

                              #29
                              Re: swapping bytes in an integer

                              On 2006-05-11, Rod Pemberton <do_not_have@bi tfoad.cmm> wrote:[color=blue]
                              > Your perspective is what's incorrect. It is portable. It's portable
                              > to any machine which uses 32-bits for 'unsigned long' which is the
                              > extreme majority of architectures in existence. It's _rare_ for an
                              > 'unsigned long' to be any other size even on 16-bit or 64-bit
                              > machines. You've attempted to redefine portability in terms of a few
                              > obscure machines.[/color]

                              On what 64-bit machines is unsigned long int a 32-bit type? That's more
                              rare than for it to be 64 bits.

                              Comment

                              • Keith Thompson

                                #30
                                Re: swapping bytes in an integer

                                "Rod Pemberton" <do_not_have@bi tfoad.cmm> writes:[color=blue]
                                > "Keith Thompson" <kst-u@mib.org> wrote in message
                                > news:lnfyjhll6f .fsf@nuthaus.mi b.org...[/color]
                                [...][color=blue][color=green]
                                >> I didn't say they're non-rare; that's not the point. The point is
                                >> that saying "rarely it's non-portable" merely obfuscates the fact that
                                >> it's *non-portable*.[/color]
                                >
                                > Your perspective is what's incorrect. It is portable. It's
                                > portable to any machine which uses 32-bits for 'unsigned long' which
                                > is the extreme majority of architectures in existence. It's _rare_
                                > for an 'unsigned long' to be any other size even on 16-bit or 64-bit
                                > machines. You've attempted to redefine portability in terms of a
                                > few obscure machines.[/color]

                                64-bit longs are not rare. 64-bit machines are not obscure. On
                                64-bit machines, 64-bit longs are much more common than 32-bit longs.
                                [color=blue][color=green]
                                >> 64-bit systems are already showing up as home PCs for everyday use,
                                >> and they're becoming more and more common.
                                >>
                                >> If you write code that works only on 32-bit systems, it's likely to
                                >> work on *most* modern systems. But why waste your time writing code
                                >> that works on most systems, when you can write *portable* code with
                                >> little additional effort?[/color]
                                >
                                > Since you (claim to) have experience in this area, feel free to post a
                                > portable solution. But, that would violate your personal no-code policy
                                > wouldn't it?[/color]

                                Stop trolling, and stop making things up.

                                --
                                Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

                                Comment

                                Working...