''From a post in news:comp.lang.tcl :'' [FPX]: Floating point values are usually transferred in IEEE format. IEEE 754-1985, "IEEE Standard for Binary Floating-Point Arithmetic" [http://standards.ieee.org/reading/ieee/std_public/description/busarch/754-1985_desc.html] defines 32-bit and 64-bit encoding formats for floating-point numbers. Normally, such values can be interpreted using Tcl's [binary] command, using the "f" and "d" formats. However, there is a catch: Tcl ultimately depends on the encoding of the "float" and "double" data types in the C language, and according to ISO C, the encoding of these data types is implementation dependent. Consequently, the manual for [binary] warns that input and output of the "f" and "d" formats is not portable. I have written the following code to read an IEEE float value, in case that your machine doesn't use IEEE natively. It also supports a "byteorder" flag that allows to read the value whether in big-endian or little-endian byteorder. proc IEEE2float {data byteorder} { if {$byteorder == 0} { set code [binary scan $data cccc se1 e2f1 f2 f3] } else { set code [binary scan $data cccc f3 f2 e2f1 se1] } set se1 [expr {($se1 + 0x100) % 0x100}] set e2f1 [expr {($e2f1 + 0x100) % 0x100}] set f2 [expr {($f2 + 0x100) % 0x100}] set f3 [expr {($f3 + 0x100) % 0x100}] set sign [expr {$se1 >> 7}] set exponent [expr {(($se1 & 0x7f) << 1 | ($e2f1 >> 7))}] set f1 [expr {$e2f1 & 0x7f}] set fraction [expr {double($f1)*0.0078125 + \ double($f2)*3.0517578125e-05 + \ double($f3)*1.19209289550781e-07}] set res [expr {($sign ? -1. : 1.) * \ pow(2.,double($exponent-127)) * \ (1. + $fraction)}] return $res } It expects a binary buffer containing an IEEE number and the byte order the number is in (0 for big-endian and 1 for little-endian). 3fa22435 yields 1.2667299509 (big-endian) or 6.1330860035e-07 (little). Here's code for the reverse transformation, from a floating-point value to IEEE format: proc float2IEEE {val byteorder} { if {$val > 0} { set sign 0 } else { set sign 1 set val [expr {-1. * $val}] } # # If the following math fails, then it's because of the # logarithm. That means that val is indistinguishable from # zero # if {[catch { set exponent [expr {int(floor(log($val)/0.69314718055994529))+127}] set fraction [expr {($val/pow(2.,double($exponent-127)))-1.}] }]} { set exponent 0 set fraction 0.0 } else { # # round off too-small values to zero, throw error for # too-large values # if {$exponent < 0} { set exponent 0 set fraction 0.0 } elseif {$exponent > 255} { error "value $val outside legal range for a float" } } set fraction [expr {$fraction * 128.}] set f1f [expr {floor($fraction)}] set fraction [expr {($fraction - $f1f) * 256.}] set f2f [expr {floor($fraction)}] set fraction [expr {($fraction - $f2f) * 256.}] set f3f [expr {floor($fraction)}] set f1 [expr {int($f1f)}] set f2 [expr {int($f2f)}] set f3 [expr {int($f3f)}] set se1 [expr {($sign ? 128 : 0) | ($exponent >> 1)}] set e2f1 [expr {(($exponent & 0x1) << 7) | $f1}] if {$byteorder == 0} { set bytes [binary format cccc $se1 $e2f1 $f2 $f3] } else { set bytes [binary format cccc $f3 $f2 $e2f1 $se1] } return $bytes } ---- Also see [1750A to Float Conversion] for converting to and from a MIL-STD-1750A 32-bit floating number. [Michael Jacobson] ~ jakeforce@home.com ---- [CL] intends to make time to demonstrate how the constants above introduce small imprecisions around the twelfth decimal place. ---- [Category Binary Data]