encoding a float

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • hurcan solter

    #1

    encoding a float

    Hi all, I am trying to convert a float value to a octet stream for
    transmission, I came up with solution like

    float deneme=3.141567 89;
    float deneme2=0.0;
    vector<unsigned charvec; //this is my buffer can con contain
    other things besides this float

    int* val=reinterpret _cast<int*>(&de neme); // gives me jeebies
    vec.push_back(( unsigned char) ((*val >24) & 0xFF ));
    vec.push_back(( unsigned char) ((*val >16) & 0xFF ));
    vec.push_back(( unsigned char) ((*val >8) & 0xFF ));
    vec.push_back(( unsigned char) ((*val >0) & 0xFF ));
    int val2=0;
    int _pos=0;
    val2+= ((int)vec[_pos++] & 0xFF) << 24;
    val2+= ((int)vec[_pos++] & 0xFF) << 16;
    val2+= ((int)vec[_pos++] & 0xFF) << 8;
    val2+= ((int)vec[_pos++] & 0xFF) << 0;
    deneme2=*reinte rpret_cast<floa t*>(&val2); //ditto

    it works, but i am not sure that this is the Right Way to do, I
    wonder if there is
    a safer or cleaner way? I tried memcpy to treat the vector as if
    an array it didn't
    work out well( although, It should work right?)
    Any pointers would be greatly appreciated...
    hurcan


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.m oderated. First time posters: Do this! ]

  • Fei Liu

    #2
    Re: encoding a float

    hurcan solter wrote:
    Hi all, I am trying to convert a float value to a octet stream for
    transmission, I came up with solution like
    >
    float deneme=3.141567 89;
    float deneme2=0.0;
    vector<unsigned charvec; //this is my buffer can con contain
    other things besides this float
    >
    int* val=reinterpret _cast<int*>(&de neme); // gives me jeebies
    vec.push_back(( unsigned char) ((*val >24) & 0xFF ));
    vec.push_back(( unsigned char) ((*val >16) & 0xFF ));
    vec.push_back(( unsigned char) ((*val >8) & 0xFF ));
    vec.push_back(( unsigned char) ((*val >0) & 0xFF ));
    int val2=0;
    int _pos=0;
    val2+= ((int)vec[_pos++] & 0xFF) << 24;
    val2+= ((int)vec[_pos++] & 0xFF) << 16;
    val2+= ((int)vec[_pos++] & 0xFF) << 8;
    val2+= ((int)vec[_pos++] & 0xFF) << 0;
    deneme2=*reinte rpret_cast<floa t*>(&val2); //ditto
    >
    it works, but i am not sure that this is the Right Way to do, I
    wonder if there is
    a safer or cleaner way? I tried memcpy to treat the vector as if
    an array it didn't
    work out well( although, It should work right?)
    Any pointers would be greatly appreciated...
    hurcan
    >
    >
    Did you look into more general framework such as soap or yaml? Boost
    also has a primitive serialization/deserialization framework.

    Fei

    Comment

    • red floyd

      #3
      Re: encoding a float

      hurcan solter wrote:
      Hi all, I am trying to convert a float value to a octet stream for
      transmission, I came up with solution like
      >
      float deneme=3.141567 89;
      float deneme2=0.0;
      vector<unsigned charvec; //this is my buffer can con contain
      other things besides this float
      >
      int* val=reinterpret _cast<int*>(&de neme); // gives me jeebies
      vec.push_back(( unsigned char) ((*val >24) & 0xFF ));
      vec.push_back(( unsigned char) ((*val >16) & 0xFF ));
      vec.push_back(( unsigned char) ((*val >8) & 0xFF ));
      vec.push_back(( unsigned char) ((*val >0) & 0xFF ));
      Gener
      int val2=0;
      int _pos=0;
      val2+= ((int)vec[_pos++] & 0xFF) << 24;
      val2+= ((int)vec[_pos++] & 0xFF) << 16;
      val2+= ((int)vec[_pos++] & 0xFF) << 8;
      val2+= ((int)vec[_pos++] & 0xFF) << 0;
      deneme2=*reinte rpret_cast<floa t*>(&val2); //ditto
      >
      it works, but i am not sure that this is the Right Way to do, I
      wonder if there is
      a safer or cleaner way? I tried memcpy to treat the vector as if
      an array it didn't
      work out well( although, It should work right?)
      Any pointers would be greatly appreciated...
      hurcan
      What about:

      float deneme = 3.14159;
      const unsigned char *const tmp_p =
      reinterpret_cas t<unsigned char *>(&deneme);
      v.assign(tmp_p, tmp_p + sizeof(&deneme) ;

      float deneme2 = 0;
      std::copy(tmp_p .begin(), tmp_p + sizeof(deneme2) ,
      reinterpret_cas t<unsigned char *>(&deneme2));

      You don't need to worry about byte ordering, etc in an int, or
      shift/masking. Just use direct copy.

      --
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.m oderated. First time posters: Do this! ]

      Comment

      • =?ISO-8859-1?Q?Erik_Wikstr=F6m?=

        #4
        Re: encoding a float

        On 2007-03-27 18:00, hurcan solter wrote:
        Hi all, I am trying to convert a float value to a octet stream for
        transmission, I came up with solution like
        >
        float deneme=3.141567 89;
        float deneme2=0.0;
        vector<unsigned charvec; //this is my buffer can con contain
        other things besides this float
        >
        int* val=reinterpret _cast<int*>(&de neme); // gives me jeebies
        vec.push_back(( unsigned char) ((*val >24) & 0xFF ));
        vec.push_back(( unsigned char) ((*val >16) & 0xFF ));
        vec.push_back(( unsigned char) ((*val >8) & 0xFF ));
        vec.push_back(( unsigned char) ((*val >0) & 0xFF ));
        int val2=0;
        int _pos=0;
        val2+= ((int)vec[_pos++] & 0xFF) << 24;
        val2+= ((int)vec[_pos++] & 0xFF) << 16;
        val2+= ((int)vec[_pos++] & 0xFF) << 8;
        val2+= ((int)vec[_pos++] & 0xFF) << 0;
        deneme2=*reinte rpret_cast<floa t*>(&val2); //ditto
        >
        it works, but i am not sure that this is the Right Way to do, I
        wonder if there is
        a safer or cleaner way? I tried memcpy to treat the vector as if
        an array it didn't
        work out well( although, It should work right?)
        Any pointers would be greatly appreciated...
        hurcan
        Seems a bit convoluted. What you want is to be able to treat the double
        as an array of unsigned chars, I'd do something like this:

        #include <iostream>

        int main()
        {
        std::cout.preci sion(10);
        double orig = 2134.4325;
        std::cout << orig << std::endl;

        unsigned char* bytes = reinterpret_cas t<unsigned char*>(&orig);

        for (int i = 0; i < sizeof(double); ++i)
        {
        std::cout << std::hex << (int)bytes[i] << std::endl;
        }

        double res = *reinterpret_ca st<double*>(byt es);

        std::cout << res << std::endl;

        std::cout << (orig == res) << std::endl;
        }

        So what I do is to cast a pointer to the double to a pointer to unsigned
        char, and as long as I know what type it was from the beginning I can
        get the length of the array using sizeof().

        As for sending the data there might be some problems. As long as the
        sending and receiving computers have the same endianness there should be
        no problem but if they don't you have to take that into account.

        --
        Erik Wikström


        [ See http://www.gotw.ca/resources/clcm.htm for info about ]
        [ comp.lang.c++.m oderated. First time posters: Do this! ]

        Comment

        • Pierre Asselin

          #5
          Re: encoding a float

          In comp.lang.c++.m oderated hurcan solter <hsolter@gmail. comwrote:
          Hi all, I am trying to convert a float value to a octet stream for
          transmission, I came up with solution like
          [ type-punning code elided ]
          Whatever you do, follow http://www.ietf.org/rfc/rfc4506.txt .

          Any pointers would be greatly appreciated...
          http://xstream.sourceforge.net/ , if an LGPL library works
          for you. If not, you can study their XDR code and reimplement
          it from scratch, taking care not to create a derivative work.


          --
          pa at panix dot com

          [ See http://www.gotw.ca/resources/clcm.htm for info about ]
          [ comp.lang.c++.m oderated. First time posters: Do this! ]

          Comment

          • James Kanze

            #6
            Re: encoding a float

            On Mar 27, 6:00 pm, "hurcan solter" <hsol...@gmail. comwrote:
            Hi all, I am trying to convert a float value to a octet stream
            In what format?
            for
            transmission, I came up with solution like
            float deneme=3.141567 89;
            float deneme2=0.0;
            vector<unsigned charvec; //this is my buffer can con contain
            other things besides this float
            int* val=reinterpret _cast<int*>(&de neme); // gives me jeebies
            vec.push_back(( unsigned char) ((*val >24) & 0xFF ));
            vec.push_back(( unsigned char) ((*val >16) & 0xFF ));
            vec.push_back(( unsigned char) ((*val >8) & 0xFF ));
            vec.push_back(( unsigned char) ((*val >0) & 0xFF ));
            int val2=0;
            int _pos=0;
            val2+= ((int)vec[_pos++] & 0xFF) << 24;
            val2+= ((int)vec[_pos++] & 0xFF) << 16;
            val2+= ((int)vec[_pos++] & 0xFF) << 8;
            val2+= ((int)vec[_pos++] & 0xFF) << 0;
            deneme2=*reinte rpret_cast<floa t*>(&val2); //ditto
            it works, but i am not sure that this is the Right Way to do, I
            wonder if there is
            a safer or cleaner way?
            The first question is the one above: what is the desired format.
            The above will only work if the internal format of a float
            corresponds exactly to the desired format. And of course, it
            also depends on int being the same size as float; I've definitly
            worked on machines where it is smaller.
            I tried memcpy to treat the vector as if
            an array it didn't
            work out well( although, It should work right?)
            To memcpy, you'd have to first increase the size of the vector,
            then pass the address of the target element. And of course,
            memcpy is even less portable than the above; it can fail between
            two different machines even if both use IEEE floating point (and
            I've seen at least one case where it failed between two
            different versions of the same compiler, on the same platform).

            --
            James Kanze (GABI Software) mailto:james.ka nze@gmail.com
            Conseils en informatique orient?e objet/
            Beratung in objektorientier ter Datenverarbeitu ng
            9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34


            --
            [ See http://www.gotw.ca/resources/clcm.htm for info about ]
            [ comp.lang.c++.m oderated. First time posters: Do this! ]

            Comment

            • andrew_nuss@yahoo.com

              #7
              Re: encoding a float

              >
              Hi all, I am trying to convert a float value to a octet stream
              >
              I have a similar problem. However, I am working within the same
              machine, passing float/double from a JVM to native code. Currently, I
              am assuming that for JNI implementations of the JVM, sizeof(jint) ==
              sizeof(jfloat) and sizeof(jlong) == sizeof(jdouble) but this might not
              be safe. I can only assume that a JVM can successfully encode a Java
              float as a C++ jfloat and a Java double as a C++ jdouble.
              >
              The first question is the one above: what is the desired format.
              The above will only work if the internal format of a float
              corresponds exactly to the desired format. And of course, it
              also depends on int being the same size as float; I've definitly
              worked on machines where it is smaller.
              >
              I tried memcpy to treat the vector as if
              an array it didn't
              work out well( although, It should work right?)
              >
              To memcpy, you'd have to first increase the size of the vector,
              then pass the address of the target element. And of course,
              memcpy is even less portable than the above; it can fail between
              two different machines even if both use IEEE floating point (and
              I've seen at least one case where it failed between two
              different versions of the same compiler, on the same platform).
              >
              What if I reinterpret the pointer to jdouble and jfloat as an unsigned
              char* and then encode as a hexstring. Won't this work as long as my
              JVM that produces the doubles and floats is the same machine and
              process that consumes them within the native code?

              Andy



              --
              [ See http://www.gotw.ca/resources/clcm.htm for info about ]
              [ comp.lang.c++.m oderated. First time posters: Do this! ]

              Comment

              • =?iso-8859-1?q?Erik_Wikstr=F6m?=

                #8
                Re: encoding a float

                On 28 Mar, 08:39, "andrew_n...@ya hoo.com" <andrew_n...@ya hoo.com>
                wrote:
                Hi all, I am trying to convert a float value to a octet stream
                >
                I have a similar problem. However, I am working within the same
                machine, passing float/double from a JVM to native code. Currently, I
                am assuming that for JNI implementations of the JVM, sizeof(jint) ==
                sizeof(jfloat) and sizeof(jlong) == sizeof(jdouble) but this might not
                be safe. I can only assume that a JVM can successfully encode a Java
                float as a C++ jfloat and a Java double as a C++ jdouble.
                >
                >
                >
                >
                >
                The first question is the one above: what is the desired format.
                The above will only work if the internal format of a float
                corresponds exactly to the desired format. And of course, it
                also depends on int being the same size as float; I've definitly
                worked on machines where it is smaller.
                >
                I tried memcpy to treat the vector as if
                an array it didn't
                work out well( although, It should work right?)
                >
                To memcpy, you'd have to first increase the size of the vector,
                then pass the address of the target element. And of course,
                memcpy is even less portable than the above; it can fail between
                two different machines even if both use IEEE floating point (and
                I've seen at least one case where it failed between two
                different versions of the same compiler, on the same platform).
                >
                What if I reinterpret the pointer to jdouble and jfloat as an unsigned
                char* and then encode as a hexstring. Won't this work as long as my
                JVM that produces the doubles and floats is the same machine and
                process that consumes them within the native code?
                Might be, it certainly seems safer than assuming things about the size
                of things. But unless this is a performance-critical part I think it
                might be worth converting the ints, doubles, etc to a human readable
                format (text) and then convert back. This way you can be sure that the
                values are preserved.

                --
                Erik Wikström



                --
                [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                [ comp.lang.c++.m oderated. First time posters: Do this! ]

                Comment

                • James Kanze

                  #9
                  Re: encoding a float

                  On Mar 28, 8:39 am, "andrew_n...@ya hoo.com" <andrew_n...@ya hoo.com>
                  wrote:
                  Hi all, I am trying to convert a float value to a octet stream
                  I have a similar problem. However, I am working within the same
                  machine, passing float/double from a JVM to native code. Currently, I
                  am assuming that for JNI implementations of the JVM, sizeof(jint) ==
                  sizeof(jfloat) and sizeof(jlong) == sizeof(jdouble) but this might not
                  be safe. I can only assume that a JVM can successfully encode a Java
                  float as a C++ jfloat and a Java double as a C++ jdouble.
                  JNI is a different situation, and you should check the JNI
                  documentation to be sure, but I believe that at the JNI
                  interface, you'll get native format, regardless of what the JVM
                  uses internally.
                  The first question is the one above: what is the desired format.
                  The above will only work if the internal format of a float
                  corresponds exactly to the desired format. And of course, it
                  also depends on int being the same size as float; I've definitly
                  worked on machines where it is smaller.
                  I tried memcpy to treat the vector as if
                  an array it didn't
                  work out well( although, It should work right?)
                  To memcpy, you'd have to first increase the size of the vector,
                  then pass the address of the target element. And of course,
                  memcpy is even less portable than the above; it can fail between
                  two different machines even if both use IEEE floating point (and
                  I've seen at least one case where it failed between two
                  different versions of the same compiler, on the same platform).
                  What if I reinterpret the pointer to jdouble and jfloat as an unsigned
                  char* and then encode as a hexstring. Won't this work as long as my
                  JVM that produces the doubles and floats is the same machine and
                  process that consumes them within the native code?
                  It depends on who's reading the stream, and why. I don't really
                  understand what you are trying to do; you can pass float and
                  double directly over the JNI interface, and they should be in
                  native format, ready for immediate use. If you're streaming
                  data (e.g. into a ByteArray), then you have to follow the same
                  rules as everyone else: decide on a format, and ensure that
                  everyone codes to it. (Converting to a hex string seems off
                  hand to combine the worst aspects of both binary and text. I
                  wouldn't do it unless it was required by some external format.)

                  --
                  James Kanze (GABI Software) mailto:james.ka nze@gmail.com
                  Conseils en informatique orient?e objet/
                  Beratung in objektorientier ter Datenverarbeitu ng
                  9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34


                  --
                  [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                  [ comp.lang.c++.m oderated. First time posters: Do this! ]

                  Comment

                  • John Moeller

                    #10
                    Re: encoding a float

                    On Mar 28, 12:39 am, "andrew_n...@ya hoo.com" <andrew_n...@ya hoo.com>
                    wrote:
                    I have a similar problem. However, I am working within the same
                    machine, passing float/double from a JVM to native code. Currently, I
                    am assuming that for JNI implementations of the JVM, sizeof(jint) ==
                    sizeof(jfloat) and sizeof(jlong) == sizeof(jdouble) but this might not
                    be safe. I can only assume that a JVM can successfully encode a Java
                    float as a C++ jfloat and a Java double as a C++ jdouble.
                    >
                    ....
                    >
                    What if I reinterpret the pointer to jdouble and jfloat as an unsigned
                    char* and then encode as a hexstring. Won't this work as long as my
                    JVM that produces the doubles and floats is the same machine and
                    process that consumes them within the native code?
                    There may be better alternatives depending upon what you want to do.
                    If you want to encode the floating-point numbers as bytes, and you
                    have a lot of them, you may want to use a java.nio.ByteBu ffer. You
                    can create a double or float view of the ByteBuffer, and the byte
                    order is always big-endian by default. If the ByteBuffer is created
                    with allocateDirect, you can pass it to native functions, and get
                    access to the byte data directly in native code. You can do the same
                    in reverse to get it back.

                    If you're talking only a few values, you probably just want to use the
                    text-encoding methods described earlier. The only problem with text-
                    encoding numbers (especially floating-point), however, is
                    localization. E.g., a "," in Germany means the same as a "." in the
                    U.S. or Britain. We've run into this problem before at my company,
                    and we decided that internally-represented numbers would just use the
                    one localization.


                    --
                    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                    [ comp.lang.c++.m oderated. First time posters: Do this! ]

                    Comment

                    Working...