443,907 Members | 2,031 Online
Need help? Post your question and get tips & solutions from a community of 443,907 IT Pros & Developers. It's quick & easy.

# interpret 4 byte as 32-bit float (IEEE-754)

 P: n/a Hello, I've read some bytes from a file and just now I can't interpret 4 bytes in this dates like a real value. An extract from my program def l32(c): return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) .... value = l32(f.read(4)) <--- 3F 8C CC CD should be 1.11 Anybody an answer ? regards gf Jul 18 '05 #1
9 Replies

 P: n/a franzkowiak wrote: I've read some bytes from a file and just now I can't interpret 4 bytes in this dates like a real value. An extract from my program: def l32(c): return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) ... value = l32(f.read(4)) <--- 3F 8C CC CD should be 1.11 OK, here's the skinny (I used blocks & views to get the answer): import struct bytes = ''.join(chr(int(txt, 16)) for txt in '3F 8C CC CD'.split()) struct.unpack('>f', bytes) I was suspicious of that first byte, thought it might be an exponent, since it seemed to have too many on bits in a row to be part of 1.11. -Scott David Daniels Sc***********@Acm.Org Jul 18 '05 #2

 P: n/a On 2005-01-15, Scott David Daniels wrote: I've read some bytes from a file and just now I can't interpret 4 bytes in this dates like a real value. OK, here's the skinny (I used blocks & views to get the answer): import struct bytes = ''.join(chr(int(txt, 16)) for txt in '3F 8C CC CD'.split()) struct.unpack('>f', bytes) Just be careful. That doesn't work for all 32-bit IEEE floating point values: import struct bytes = '\xff\xff\xff\xff' print struct.unpack('>f',bytes) (-6.8056469327705772e+38,) 0xffffff is _not_ -6.8...e38. It's a NaN. IIRC, it doesn't work for infinities either. I haven't tried denormals. -- Grant Edwards grante Yow! It's hard being at an ARTIST!! visi.com Jul 18 '05 #3

 P: n/a Scott David Daniels schrieb: franzkowiak wrote: I've read some bytes from a file and just now I can't interpret 4 bytes in this dates like a real value. An extract from my program: def l32(c): return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) ... value = l32(f.read(4)) <--- 3F 8C CC CD should be 1.11 OK, here's the skinny (I used blocks & views to get the answer): import struct bytes = ''.join(chr(int(txt, 16)) for txt in '3F 8C CC CD'.split()) struct.unpack('>f', bytes) I was suspicious of that first byte, thought it might be an exponent, since it seemed to have too many on bits in a row to be part of 1.11. -Scott David Daniels Sc***********@Acm.Org Ok, I the string exist with "mystr = f.read(4)" and the solution for this case is in your line "struct.unpack('>f', bytes)" But what can I do when I want the interpret the content from the Integer myInt (*myInt = 0x3F8CCCCD) like 4-byte-real ? This was stored with an othes system in a binary file to CD CC 8C 3F and now is it in python in value. The conversion is not possible. It's right... one of this bytes is an exponent. I want copy the memory content from the "value address" to "myReal address" and use print "%f" %myReal. Is myReal then the right format ? What can I do with python, in FORTH is it simple ( >f f. ) gf Jul 18 '05 #4

 P: n/a G.Franzkowiak wrote: Scott David Daniels schrieb: franzkowiak wrote: I've read some bytes from a file and just now I can't interpret 4 bytes in this dates like a real value. An extract from my program: def l32(c): return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) ... value = l32(f.read(4)) <--- 3F 8C CC CD should be 1.11 OK, here's the skinny (I used blocks & views to get the answer): import struct bytes = ''.join(chr(int(txt, 16)) for txt in '3F 8C CC CD'.split()) struct.unpack('>f', bytes) I was suspicious of that first byte, thought it might be an exponent, since it seemed to have too many on bits in a row to be part of 1.11. -Scott David Daniels Sc***********@Acm.Org Ok, I the string exist with "mystr = f.read(4)" and the solution for this case is in your line "struct.unpack('>f', bytes)" But what can I do when I want the interpret the content from the Integer myInt (*myInt = 0x3F8CCCCD) like 4-byte-real ? This was stored with an othes system in a binary file to CD CC 8C 3F and now is it in python in value. The conversion is not possible. It's right... one of this bytes is an exponent. I want copy the memory content from the "value address" to "myReal address" and use print "%f" %myReal. Is myReal then the right format ? What can I do with python, in FORTH is it simple ( >f f. ) gf If you really want to do this kind of byte fiddling: http://members.dsl-only.net/~daniels/block.html Then: from block import Block, View b = Block(4) # enough space for one float (more is fine) iv = View('i', b) # getting to it as an integer fv = View('f', b) # same memory as floating point iv[0] = 0x3F8CCCCD # Here is a sample just using the integer print fv[0] On an Intel/Amd/Generic "PC" machine, you should get 1.1 -Scott David Daniels Sc***********@Acm.Org Jul 18 '05 #5

 P: n/a "Scott David Daniels" wrote in message news:41********@nntp0.pdx.net... franzkowiak wrote: I've read some bytes from a file and just now I can't interpret 4 bytes in this dates like a real value. An extract from my program: def l32(c): return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) ... value = l32(f.read(4)) <--- 3F 8C CC CD should be 1.11 OK, here's the skinny (I used blocks & views to get the answer): import struct bytes = ''.join(chr(int(txt, 16)) for txt in '3F 8C CC CD'.split()) struct.unpack('>f', bytes) I was suspicious of that first byte, thought it might be an exponent, since it seemed to have too many on bits in a row to be part of 1.11. I believe exponents are typically stored as a positive offset from the largest negative exponent. 3F8 is about half of 7FF, so that seems about right for an actual exponent of 0. Terry J. Reedy Jul 18 '05 #6

 P: n/a Scott David Daniels schrieb: G.Franzkowiak wrote: Scott David Daniels schrieb: franzkowiak wrote: I've read some bytes from a file and just now I can't interpret 4 bytes in this dates like a real value. An extract from my program: def l32(c): return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) ... value = l32(f.read(4)) <--- 3F 8C CC CD should be 1.11 OK, here's the skinny (I used blocks & views to get the answer): import struct bytes = ''.join(chr(int(txt, 16)) for txt in '3F 8C CC CD'.split()) struct.unpack('>f', bytes) I was suspicious of that first byte, thought it might be an exponent, since it seemed to have too many on bits in a row to be part of 1.11. -Scott David Daniels Sc***********@Acm.Org Ok, I the string exist with "mystr = f.read(4)" and the solution for this case is in your line "struct.unpack('>f', bytes)" But what can I do when I want the interpret the content from the Integer myInt (*myInt = 0x3F8CCCCD) like 4-byte-real ? This was stored with an othes system in a binary file to CD CC 8C 3F and now is it in python in value. The conversion is not possible. It's right... one of this bytes is an exponent. I want copy the memory content from the "value address" to "myReal address" and use print "%f" %myReal. Is myReal then the right format ? What can I do with python, in FORTH is it simple ( >f f. ) gf If you really want to do this kind of byte fiddling: http://members.dsl-only.net/~daniels/block.html Then: from block import Block, View b = Block(4) # enough space for one float (more is fine) iv = View('i', b) # getting to it as an integer fv = View('f', b) # same memory as floating point iv[0] = 0x3F8CCCCD # Here is a sample just using the integer print fv[0] On an Intel/Amd/Generic "PC" machine, you should get 1.1 -Scott David Daniels Sc***********@Acm.Org That's good :-)) I'm missing the makefile ;-) I'm using the other world... right Thank you Jul 18 '05 #7

 P: n/a G.Franzkowiak wrote: Scott David Daniels schrieb: If you really want to do this kind of byte fiddling: http://members.dsl-only.net/~daniels/block.html Then: from block import Block, View b = Block(4) # enough space for one float (more is fine) iv = View('i', b) # getting to it as an integer fv = View('f', b) # same memory as floating point iv[0] = 0x3F8CCCCD # Here is a sample just using the integer print fv[0] On an Intel/Amd/Generic "PC" machine, you should get 1.1 That's good :-)) I'm missing the makefile ;-) I'm using the other world... right There's a lot more than one other world. distlib is your friend. There is no makefile. If you are not on a windows box, get the source, extract the files from the zip, and run: python setup.py install -Scott David Daniels Sc***********@Acm.Org Jul 18 '05 #8