Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Converting 4 bytes to a float

Reply
Thread Tools

Converting 4 bytes to a float

 
 
Larry.Martell@gmail.com
Guest
Posts: n/a
 
      05-09-2007
I have a situation where I have to read in 4 values from a text file,
then convert that into a float that I can use for arithmetic.

For example, the file contains "85,170,174,214" - I read this in, and
split it into an array, @d

In C, I would do something akin to this:

union convert_float32 {
float f; // float view
unsigned int i; // uint32 view
} c;
unsigned char i[4];
char *q;

for (int j=0; j<4; j++) i[j] = (unsigned char)strtoul(d[j], &q, 10);
c.i = ((unsigned int)i[0] << 24) | ((unsigned int)i[1] << 16) |
((unsigned int)i[2] << | (unsigned int)i[3];

and c.f would have the value I want (in this example
23458486419456.000000)

Is there some way I can achieve the result with perl?

TIA!
-larry




How can I do a similar conversion in perl?

 
Reply With Quote
 
 
 
 
Brian McCauley
Guest
Posts: n/a
 
      05-09-2007
On May 9, 1:35 am, "(E-Mail Removed)" <(E-Mail Removed)>
wrote:
> I have a situation where I have to read in 4 values from a text file,
> then convert that into a float that I can use for arithmetic.
>
> For example, the file contains "85,170,174,214" - I read this in, and
> split it into an array, @d
>
> In C, I would do something akin to this:
>
> union convert_float32 {
> float f; // float view
> unsigned int i; // uint32 view} c;
>
> unsigned char i[4];
> char *q;
>
> for (int j=0; j<4; j++) i[j] = (unsigned char)strtoul(d[j], &q, 10);
> c.i = ((unsigned int)i[0] << 24) | ((unsigned int)i[1] << 16) |
> ((unsigned int)i[2] << | (unsigned int)i[3];
>
> and c.f would have the value I want (in this example
> 23458486419456.000000)
>
> Is there some way I can achieve the result with perl?
>
> TIA!
> -larry
>
> How can I do a similar conversion in perl?



 
Reply With Quote
 
 
 
 
Brian McCauley
Guest
Posts: n/a
 
      05-09-2007
On May 9, 1:35 am, "(E-Mail Removed)" <(E-Mail Removed)>
wrote:
> I have a situation where I have to read in 4 values from a text file,
> then convert that into a float that I can use for arithmetic.
>
> For example, the file contains "85,170,174,214" - I read this in, and
> split it into an array, @d
>
> In C, I would do something akin to this:
>
> union convert_float32 {
> float f; // float view
> unsigned int i; // uint32 view
>} c;



> unsigned char i[4];
> char *q;
>
> for (int j=0; j<4; j++) i[j] = (unsigned char)strtoul(d[j], &q, 10);
> c.i = ((unsigned int)i[0] << 24) | ((unsigned int)i[1] << 16) |
> ((unsigned int)i[2] << | (unsigned int)i[3];
>
> and c.f would have the value I want (in this example
> 23458486419456.000000)


Actually it would make more sense to get rid of the intermediate step.

union convert_float32 {
float f; // float view
unsigned char i[4]; // 4 byte view
} c;

> Is there some way I can achieve the result with perl?


You are looking for the pack() and unpack() functions.

 
Reply With Quote
 
Dr.Ruud
Guest
Posts: n/a
 
      05-09-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) schreef:

> I have a situation where I have to read in 4 values from a text file,
> then convert that into a float that I can use for arithmetic.


First convert the values into a buffer of 4 bytes. Then use unpack().
See perldoc -f unpack.


$ perl -wle 'print length pack "f", 1.23'
4

$ perl -wle 'print ord for split "", pack "f", 1.23'
164
112
157
63

$ perl -wle 'print unpack "f", chr(164).chr(112).chr(157).chr(63)'
1.23000001907349

--
Affijn, Ruud

"Gewoon is een tijger."
 
Reply With Quote
 
Larry.Martell@gmail.com
Guest
Posts: n/a
 
      05-09-2007
On May 9, 12:37 am, Brian McCauley <(E-Mail Removed)> wrote:
> On May 9, 1:35 am, "(E-Mail Removed)" <(E-Mail Removed)>
> wrote:
>
>
>
> > I have a situation where I have to read in 4 values from a text file,
> > then convert that into a float that I can use for arithmetic.

>
> > For example, the file contains "85,170,174,214" - I read this in, and
> > split it into an array, @d

>
> > In C, I would do something akin to this:

>
> > union convert_float32 {
> > float f; // float view
> > unsigned int i; // uint32 view
> >} c;
> > unsigned char i[4];
> > char *q;

>
> > for (int j=0; j<4; j++) i[j] = (unsigned char)strtoul(d[j], &q, 10);
> > c.i = ((unsigned int)i[0] << 24) | ((unsigned int)i[1] << 16) |
> > ((unsigned int)i[2] << | (unsigned int)i[3];

>
> > and c.f would have the value I want (in this example
> > 23458486419456.000000)

>
> Actually it would make more sense to get rid of the intermediate step.
>
> union convert_float32 {
> float f; // float view
> unsigned char i[4]; // 4 byte view
>
> } c;
> > Is there some way I can achieve the result with perl?

>
> You are looking for the pack() and unpack() functions.


Thanks - I got this to work using unpack().

-larry


 
Reply With Quote
 
Larry.Martell@gmail.com
Guest
Posts: n/a
 
      05-09-2007
On May 9, 12:51 am, "Dr.Ruud" <(E-Mail Removed)> wrote:
> (E-Mail Removed) schreef:
>
> > I have a situation where I have to read in 4 values from a text file,
> > then convert that into a float that I can use for arithmetic.

>
> First convert the values into a buffer of 4 bytes. Then use unpack().
> See perldoc -f unpack.
>
> $ perl -wle 'print length pack "f", 1.23'
> 4
>
> $ perl -wle 'print ord for split "", pack "f", 1.23'
> 164
> 112
> 157
> 63
>
> $ perl -wle 'print unpack "f", chr(164).chr(112).chr(157).chr(63)'
> 1.23000001907349


Thanks much - this is exactly what I was looking for. I had read about
pack and unpack,
but I had their functionality reversed. Your post clarified things for
me. I had to put the
bytes in in reverse order (to deal with the little-endiness of my
machine), but once I did
that I got the correct result:

$ perl -wle 'print unpack "f",chr(214).chr(174).chr(170).chr(85)'
23458486419456

Thanks again!
-larry

 
Reply With Quote
 
Peter J. Holzer
Guest
Posts: n/a
 
      05-13-2007
On 2007-05-09 06:37, Brian McCauley <(E-Mail Removed)> wrote:
> On May 9, 1:35 am, "(E-Mail Removed)" <(E-Mail Removed)>
> wrote:
>> In C, I would do something akin to this:
>>
>> union convert_float32 {
>> float f; // float view
>> unsigned int i; // uint32 view
>>} c;

>
>
>> unsigned char i[4];
>> char *q;
>>
>> for (int j=0; j<4; j++) i[j] = (unsigned char)strtoul(d[j], &q, 10);
>> c.i = ((unsigned int)i[0] << 24) | ((unsigned int)i[1] << 16) |
>> ((unsigned int)i[2] << | (unsigned int)i[3];
>>
>> and c.f would have the value I want (in this example
>> 23458486419456.000000)

>
> Actually it would make more sense to get rid of the intermediate step.
>
> union convert_float32 {
> float f; // float view
> unsigned char i[4]; // 4 byte view
> } c;


I don't think so. You are introducing an endian dependency which the
OP's code didn't have.


>> Is there some way I can achieve the result with perl?

>
> You are looking for the pack() and unpack() functions.


Unfortunately pack does't have a format for "single precision IEEE-754
floating point number in network byte order", so - as the OP already
found out - you either need to know the endianness of your platform, or
you need to convert from network (big endian) byte order to native byte
order first:

$fp_value = unpack('f', pack('L', unpack('N', $bytes)));

hp

--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | (E-Mail Removed) |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
 
Reply With Quote
 
 
 
Reply

Thread Tools

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 On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
float to string to float, with first float == second float Carsten Fuchs C++ 45 10-08-2009 09:47 AM
PLEASE HELP - Strange problem converting from bytes to float cpptutor2000@yahoo.com Java 6 03-23-2008 06:40 PM
converting 'float (*)[4]' to 'const float**' mathieu C++ 9 09-15-2007 09:10 AM
need code to convert float format to internal java float format which is kept in 4 bytes integer Andy Java 7 05-10-2004 09:26 PM
Re: float->byte->float is same with original float image. why float->ubyte->float is different??? bd C Programming 0 07-07-2003 12:09 AM



Advertisments