experimenting with unions - byteswap approach..

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • ma740988@pegasus.cc.ucf.edu

    #1

    experimenting with unions - byteswap approach..


    Consider the source snippet:

    union to_uchar
    {
    int i;
    unsigned int ui;
    long l;
    unsigned long ul;
    short s;
    unsigned short us;
    double d;
    unsigned char uc[8];

    void byteSwap(int siz)
    {
    int idx = 0;
    int jdx = siz-1;
    while (idx < jdx)
    {
    std::swap(uc[idx], uc[jdx]);
    idx++, jdx--;
    }
    }
    to_uchar(int ii) : i(ii) { swap(i); }
    to_uchar(double dd) : d(dd) { swap(d); }
    unsigned char* getBuf() { return uc; }

    static void swap(int& i)
    {
    to_uchar x = i; //[1]
    x.byteSwap(size of(i));
    i = x.i;
    }
    static void swap(double& d)
    {
    to_uchar x = d; //[2]
    x.byteSwap(size of(d));
    d = x.d;
    }

    };


    int main()
    {
    double d = 12345.678;
    to_uchar::swap( d);
    int i = 12345;
    to_uchar::swap( i);

    to_uchar iuc(12345);
    unsigned char* bufi = iuc.getBuf();
    to_uchar duc(12345.678);
    unsigned char* bufd = duc.getBuf();
    }

    the lines indicated by [1] and [2] above results in exceptions but this
    is one of those cases where I dont fully understand why or what teh
    solution is.

    Thanks in advance

  • David Hilsee

    #2
    Re: experimenting with unions - byteswap approach..

    <ma740988@pegas us.cc.ucf.edu> wrote in message
    news:1125533764 .972952.243820@ g49g2000cwa.goo glegroups.com.. .[color=blue]
    >
    > Consider the source snippet:
    >
    > union to_uchar
    > {
    > int i;
    > unsigned int ui;
    > long l;
    > unsigned long ul;
    > short s;
    > unsigned short us;
    > double d;
    > unsigned char uc[8];
    >
    > void byteSwap(int siz)
    > {
    > int idx = 0;
    > int jdx = siz-1;
    > while (idx < jdx)
    > {
    > std::swap(uc[idx], uc[jdx]);
    > idx++, jdx--;
    > }
    > }
    > to_uchar(int ii) : i(ii) { swap(i); }
    > to_uchar(double dd) : d(dd) { swap(d); }
    > unsigned char* getBuf() { return uc; }
    >
    > static void swap(int& i)
    > {
    > to_uchar x = i; //[1]
    > x.byteSwap(size of(i));
    > i = x.i;
    > }
    > static void swap(double& d)
    > {
    > to_uchar x = d; //[2]
    > x.byteSwap(size of(d));
    > d = x.d;
    > }
    >
    > };
    >
    >
    > int main()
    > {
    > double d = 12345.678;
    > to_uchar::swap( d);
    > int i = 12345;
    > to_uchar::swap( i);
    >
    > to_uchar iuc(12345);
    > unsigned char* bufi = iuc.getBuf();
    > to_uchar duc(12345.678);
    > unsigned char* bufd = duc.getBuf();
    > }
    >
    > the lines indicated by [1] and [2] above results in exceptions but this
    > is one of those cases where I dont fully understand why or what teh
    > solution is.[/color]

    I'm not sure what you're trying to do here, but your constructors are a
    little screwy, and it has nothing to do with unions.

    This constructor...

    to_uchar(int ii) : i(ii) { swap(i); }

    calls void to_uchar::swap( int& i)...

    to_uchar x = i; //[1]

    which constructs a to_uchar from an int (invokes the to_uchar(int ii)
    constructor)...

    to_uchar(int ii) : i(ii) { swap(i); }

    which calls void to_uchar::swap( int& i)...

    to_uchar x = i; //[1]

    which constructs a to_uchar from an int (invokes the to_uchar(int ii)
    constructor)...

    I think you can see where this is going (infinite recursion). It looks like
    the other constructor suffers from the same problem.

    --
    David Hilsee


    Comment

    • Maxim Yegorushkin

      #3
      Re: experimenting with unions - byteswap approach..


      ma740988@pegasu s.cc.ucf.edu wrote:

      []
      [color=blue]
      > int main()
      > {
      > double d = 12345.678;
      > to_uchar::swap( d);
      > int i = 12345;
      > to_uchar::swap( i);
      >
      > to_uchar iuc(12345);
      > unsigned char* bufi = iuc.getBuf();
      > to_uchar duc(12345.678);
      > unsigned char* bufd = duc.getBuf();
      > }[/color]

      Why don't you use std::reverse()?

      template<class T>
      void byteswap(T* t)
      {
      std::reverse(re interpret_cast< char*>(t), reinterpret_cas t<char*>(t
      + 1));
      }

      By the way, you can't byteswap a floating point number (float, double,
      ....), since not any bit pattern is a valid floating point number binary
      representation.

      Comment

      • ma740988@pegasus.cc.ucf.edu

        #4
        Re: experimenting with unions - byteswap approach..


        || By the way, you can't byteswap a floating point number (float,
        double,
        || ...), since not any bit pattern is a valid floating point number
        binary
        || representation.

        Maxim, thanks for the suggestion.... So what do you do with floats
        (doubles) when you have endian issues across platforms? IOW the
        sender transmits - say 9.2 and the receiver sees some convoluted number.

        Comment

        • Maxim Yegorushkin

          #5
          Re: experimenting with unions - byteswap approach..


          ma740988@pegasu s.cc.ucf.edu wrote:[color=blue]
          > || By the way, you can't byteswap a floating point number (float,
          > double,
          > || ...), since not any bit pattern is a valid floating point number
          > binary
          > || representation.
          >
          > Maxim, thanks for the suggestion.... So what do you do with floats
          > (doubles) when you have endian issues across platforms? IOW the
          > sender transmits - say 9.2 and the receiver sees some convoluted number.[/color]

          I use some binary format and a library, such as XDR.

          Alternatively, you may extract mantissa and exponent as integers, send
          and reassemble the number on the receiving side.

          Comment

          • mlimber

            #6
            Re: experimenting with unions - byteswap approach..

            ma740988@pegasu s.cc.ucf.edu wrote:[color=blue]
            > Maxim, thanks for the suggestion.... So what do you do with floats
            > (doubles) when you have endian issues across platforms? IOW the
            > sender transmits - say 9.2 and the receiver sees some convoluted number.[/color]

            You could also use text since different processors sometimes use
            different floating point formats. See these FAQs:



            Cheers! --M

            Comment

            • ma740988@pegasus.cc.ucf.edu

              #7
              Re: experimenting with unions - byteswap approach..

              Ironically, you brought this up becasue serilization is the approach
              used.
              I need to delve more into the text 'approach' so I suspect I'll peruse
              the web to get a feel for how this all works (somebody should have
              something that shows this).

              Being a little more than an intermediate apprentice :) it'll take me a
              few to get this right.

              Thanks

              Comment

              • mlimber

                #8
                Re: experimenting with unions - byteswap approach..

                ma740988@pegasu s.cc.ucf.edu wrote:[color=blue]
                > Ironically, you brought this up becasue serilization is the approach
                > used.
                > I need to delve more into the text 'approach' so I suspect I'll peruse
                > the web to get a feel for how this all works (somebody should have
                > something that shows this).
                >
                > Being a little more than an intermediate apprentice :) it'll take me a
                > few to get this right.
                >
                > Thanks[/color]

                You might also want to consider using the Boost serialization library:



                Cheers! --M

                Comment

                Working...