Account Options

  1. Sign in
Google Groups Home
« Groups Home
float2IEEE numbers - 64 bit?
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  4 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Ihug  
View profile  
 More options Jul 19 2005, 1:01 am
Newsgroups: comp.lang.tcl
From: "Ihug" <p...@fastbase.co.nz>
Date: Tue, 19 Jul 2005 17:01:56 +1200
Local: Tues, Jul 19 2005 1:01 am
Subject: float2IEEE numbers - 64 bit?
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?


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ihug  
View profile  
 More options Jul 19 2005, 8:47 pm
Newsgroups: comp.lang.tcl
From: "Ihug" <p...@fastbase.co.nz>
Date: Wed, 20 Jul 2005 12:47:44 +1200
Local: Tues, Jul 19 2005 8:47 pm
Subject: Re: float2IEEE numbers - 64 bit?
I found my own solution by taking the original wiki script and maintaining
it myself for double precion:
(there may be bugs!!!)

proc ieee754 { value } {
 # covert value to double precision IEEE754 number
 if {$value > 0} {
  set sign 0
 } else {
  set sign 1
  set value [expr {-1. * $value}]
 }

 # If the following math fails, then it's because of the logarithm. That
means that value is indistinguishable from zero
 if {[catch {
  set exponent [expr {int(floor(log($value)/0.69314718055994529))+1023}]
  set fraction [expr {($value/pow(2.,double($exponent-1023)))-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 > 2047} {
   error "value $value outside legal range for a float"
  }
 }

 set fraction [expr {$fraction * 16.}]
 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 fraction [expr {($fraction - $f3f) * 256.}]
 set f4f      [expr {floor($fraction)}]

 set fraction [expr {($fraction - $f4f) * 256.}]
 set f5f      [expr {floor($fraction)}]

 set fraction [expr {($fraction - $f5f) * 256.}]
 set f6f      [expr {floor($fraction)}]

 set fraction [expr {($fraction - $f6f) * 256.}]
 set f7f      [expr {floor($fraction)}]

 for {set i 1} {$i <= 7} {incr i} {
  set var "f$i"
  append var "f"
  set f$i [expr {int([set $var])}]
 }

 set se1 [expr {($sign ? 128 : 0) | ($exponent >> 4)}]
 set e2f1 [expr {(($exponent & 15) * 16) | $f1}]

 set bytes [binary format cccccccc $f7 $f6 $f5 $f4 $f3 $f2 $e2f1 $se1]

 return $bytes

}
"Ihug" <p...@fastbase.co.nz> wrote in message

news:dbi1fv$utu$1@lust.ihug.co.nz...


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kevin Kenny  
View profile  
 More options Jul 20 2005, 9:05 am
Newsgroups: comp.lang.tcl
From: Kevin Kenny <kenn...@acm.org>
Date: Wed, 20 Jul 2005 09:05:10 -0400
Local: Wed, Jul 20 2005 9:05 am
Subject: Re: float2IEEE numbers - 64 bit?

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


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ihug  
View profile  
 More options Jul 20 2005, 4:13 pm
Newsgroups: comp.lang.tcl
From: "Ihug" <p...@fastbase.co.nz>
Date: Thu, 21 Jul 2005 08:13:16 +1200
Local: Wed, Jul 20 2005 4:13 pm
Subject: Re: float2IEEE numbers - 64 bit?
Thanks for your input. As you can see from my second post I modified the
existing 32bit output program I found on the wiki for 64 bits.

I needed the output procedure because I am creating Excel binary files
directly (BIFF file format) and they use IEEE754 64 bit (double) numbers.

Of course, usually internal number storage and big/little endian should be
fully transparent.

Thanks again.
Peter Campbell.

"Kevin Kenny" <kenn...@acm.org> wrote in message

news:3k70g7Ft33qtU1@individual.net...


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »