Connecting Tech Pros Worldwide Help | Site Map
 
 
LinkBack Thread Tools Search this Thread
  #1  
Old March 27th, 2007, 04:05 PM
hurcan solter
Guest
 
Posts: n/a
Default 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.14156789;
float deneme2=0.0;
vector<unsigned charvec; //this is my buffer can con contain
other things besides this float

int* val=reinterpret_cast<int*>(&deneme); // 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=*reinterpret_cast<float*>(&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++.moderated. First time posters: Do this! ]

  #2  
Old March 27th, 2007, 05:15 PM
Fei Liu
Guest
 
Posts: n/a
Default Re: encoding a float

hurcan solter wrote:
Quote:
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.14156789;
float deneme2=0.0;
vector<unsigned charvec; //this is my buffer can con contain
other things besides this float
>
int* val=reinterpret_cast<int*>(&deneme); // 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=*reinterpret_cast<float*>(&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
  #3  
Old March 27th, 2007, 07:05 PM
red floyd
Guest
 
Posts: n/a
Default Re: encoding a float

hurcan solter wrote:
Quote:
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.14156789;
float deneme2=0.0;
vector<unsigned charvec; //this is my buffer can con contain
other things besides this float
>
int* val=reinterpret_cast<int*>(&deneme); // 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
Quote:
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=*reinterpret_cast<float*>(&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_cast<unsigned char *>(&deneme);
v.assign(tmp_p, tmp_p + sizeof(&deneme);

float deneme2 = 0;
std::copy(tmp_p.begin(), tmp_p + sizeof(deneme2),
reinterpret_cast<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++.moderated. First time posters: Do this! ]

  #4  
Old March 27th, 2007, 07:05 PM
=?ISO-8859-1?Q?Erik_Wikstr=F6m?=
Guest
 
Posts: n/a
Default Re: encoding a float

On 2007-03-27 18:00, hurcan solter wrote:
Quote:
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.14156789;
float deneme2=0.0;
vector<unsigned charvec; //this is my buffer can con contain
other things besides this float
>
int* val=reinterpret_cast<int*>(&deneme); // 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=*reinterpret_cast<float*>(&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.precision(10);
double orig = 2134.4325;
std::cout << orig << std::endl;

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

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

double res = *reinterpret_cast<double*>(bytes);

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++.moderated. First time posters: Do this! ]

  #5  
Old March 27th, 2007, 07:05 PM
Pierre Asselin
Guest
 
Posts: n/a
Default Re: encoding a float

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

Quote:
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++.moderated. First time posters: Do this! ]

  #6  
Old March 27th, 2007, 07:15 PM
James Kanze
Guest
 
Posts: n/a
Default Re: encoding a float

On Mar 27, 6:00 pm, "hurcan solter" <hsol...@gmail.comwrote:
Quote:
Hi all, I am trying to convert a float value to a octet stream
In what format?
Quote:
for
transmission, I came up with solution like
Quote:
float deneme=3.14156789;
float deneme2=0.0;
vector<unsigned charvec; //this is my buffer can con contain
other things besides this float
Quote:
int* val=reinterpret_cast<int*>(&deneme); // 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=*reinterpret_cast<float*>(&val2); //ditto
Quote:
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.
Quote:
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.kanze@gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
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++.moderated. First time posters: Do this! ]

  #7  
Old March 28th, 2007, 06:45 AM
andrew_nuss@yahoo.com
Guest
 
Posts: n/a
Default Re: encoding a float

>
Quote:
Quote:
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.
Quote:
>
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.
>
Quote:
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++.moderated. First time posters: Do this! ]

  #8  
Old March 28th, 2007, 08:25 AM
=?iso-8859-1?q?Erik_Wikstr=F6m?=
Guest
 
Posts: n/a
Default Re: encoding a float

On 28 Mar, 08:39, "andrew_n...@yahoo.com" <andrew_n...@yahoo.com>
wrote:
Quote:
Quote:
Quote:
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.
>
>
>
>
>
Quote:
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.
>
Quote:
Quote:
I tried memcpy to treat the vector as if
an array it didn't
work out well( although, It should work right?)
>
Quote:
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++.moderated. First time posters: Do this! ]

  #9  
Old March 28th, 2007, 01:35 PM
James Kanze
Guest
 
Posts: n/a
Default Re: encoding a float

On Mar 28, 8:39 am, "andrew_n...@yahoo.com" <andrew_n...@yahoo.com>
wrote:
Quote:
Quote:
Quote:
Hi all, I am trying to convert a float value to a octet stream
Quote:
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.
Quote:
Quote:
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.
Quote:
Quote:
Quote:
I tried memcpy to treat the vector as if
an array it didn't
work out well( although, It should work right?)
Quote:
Quote:
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).
Quote:
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.kanze@gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
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++.moderated. First time posters: Do this! ]

  #10  
Old March 28th, 2007, 07:25 PM
John Moeller
Guest
 
Posts: n/a
Default Re: encoding a float

On Mar 28, 12:39 am, "andrew_n...@yahoo.com" <andrew_n...@yahoo.com>
wrote:
Quote:
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.
>
....
Quote:
>
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.ByteBuffer. 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++.moderated. First time posters: Do this! ]

 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 205,338 network members.