Ihug wrote:
> I am trying to write IEEE 754 64 bit numbers.
> The following wiki page has a procedure "float2IEEE" that writes a 32 bit
> number.
> http://wiki.tcl.tk/756
> How would I modify this to output 64 bit?
> Is this possible/easy?
Do you need hexadecimal? Binary? Simply to ensure that the
number that you read matches the number you wrote?
In particular, have you a need to support a machine whose native
format is *not* IEEE-754? There are few such machines left, and
if you *do* have such a need, I need to know, since right now the
plan is to desupport them in 8.5.
From easiest to most difficult:
(1) If all you need is assurance that a number will be bit-for-bit
the same on input that it was on output, format it to precisely
seventeen decimal digits, no more, no less. Either
set ::tcl_precision 17; puts $theFloat
or
puts [format %.17g $theFloat]
will do the trick. (Caveat: This presumes that your sscanf
and sprintf are standards-compliant. Not all are.) In 8.5,
simply [puts $theFloat] will do just fine without messing
with ::tcl_precision; the default value of tcl_precision
becomes "as many digits as are needed to guarantee correct
reconstruction of the number on input."
(2) If you need the number in binary because you're putting it
to external media, then
[binary format d $theFloat]
will give the floating point number as a string of eight
bytes in the native byte order.
(3) If you need a specific endianity,
things get a trifle more complicated in 8.4. You have to
determine the machine's endianity:
binary scan [binary format d 1.0] w test
switch -exact [format %16lx $test] {
3ff0000000000000 {
set big false
}
0000000000000f3f {
set big true
}
default {
error "machine does not have IEEE-754"
}
}
Now, to write a float out big-endian:
if {$big} {
binary scan [binary format d $theFloat] W bits
} else {
binary scan [binary format d $theFloat] w bits
}
set result [binary format W $bits]
Change the 'W' in the last line to a 'w' to write
little-endian instead, or to write hexadecimal, change
it to:
puts [format %16x $bits]
8.5 makes this process somewhat easier, because the [binary]
command adds the 'q' and 'Q' format groups to format 'double's
in a specific endianity.
I hope this has covered everything you need; feel free to
ask again if it hasn't.
--
73 de ke9tv/2, Kevin