( Title: Convert a raw float hex string to an ANS Forth default float File: rawhex2float.fs Version: 0.1.0 Author: David N. Williams License: LGPL Last revision: March 15, 2009 ) \ Copyright (C) 2003, 2009 David N. Williams ( This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or at your option any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. Unattributed changes are by dnw. The last revision date above may reflect cosmetic changes not logged here. Version 0.1.0 4-Jan-03 * Started. 1-Feb-03 * Released. 15-Mar-09 * Replaced "0." by "0 0". * Made example compile conditionally. The main word here is RAW-HEX>FLOAT. It is a string variant of a word in Petrus' I754.PET: t! [ x1 x2 x3 x4 x5 a-addr -- ] store ten bytes at a-addr, little endian The following code has an environmental dependence on lower case. It also assumes that raw floats are represented in memory as contiguous sets of bytes that are totally big-endian or little-endian, with the raw representation of -1E nonzero in the logical first byte and zero in the logical last byte. There is a dependence on ANS default floats through the words FALIGNED, F!, and F@. These could be replaced, for example, by SFALIGNED, SF!, and SF@. The example assumes the default to be the IEEE-754 64-bit, double precision type. ) s" FLOATING-EXT" environment? [IF] ( flag) drop \ marker -conversion-code : hex-byte ( caddr u -- caddr+2 u-2 byte ) base @ >r hex over 0 0 rot 2 >number ( caddr u dbyte=0 addr #rem) ABORT" ***Not a hex string." ( dhi=0 addr) 2drop ( byte) >r 2 /string r> ( byte) r> base ! ; : raw-hex>float ( caddr u -- f: f ) ( u) dup 2 floats <> ABORT" ***Wrong size for raw float string." pad faligned dup [ -1E pad faligned dup f! c@ ] [IF] \ floats are big endian float+ swap ( &end+1 &start) DO hex-byte i c! LOOP [ELSE] float+ 1- ( &start &end) DO hex-byte i c! -1 +LOOP [THEN] ( caddr' 0) 2drop pad faligned f@ ; true [IF] \ EXAMPLE \ The example below assumes an IEEE 754 system with \ 64-bit floats in memory. 1 floats 8 = [IF] s" 4003504F333F9DE6" raw-hex>float ( f: r2p1) s" 3CA21165F626CDD5" raw-hex>float ( f: t2p1) \ The floats are stacked, so we can throw away the code: \ -conversion-code ( f: t2p1) fconstant t2p1 ( f: r2p1) fconstant r2p1 \ The following may not work as expected with some \ implementations of F.: 39 set-precision cr 1 spaces r2p1 f. cr .( +) t2p1 f. cr .( ------------------------------------------) cr .( 2.414213562373095048801688724209698078570) cr .( The last number is 1 + sqrt[2] to 40 significant figures.) cr .( Adding the first two should be correct to about 32 figures.) cr [ELSE] .( ***Example requires IEEE-754, 64-bit floats.) [THEN] [THEN] \ EXAMPLE [ELSE] .( ***Floating point not available.) [THEN]