Stata The Stata listserver
[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

st: RE: Floating-point reals, hexadecimal and decimals


From   Joly.Patrick@ic.gc.ca
To   statalist@hsphsun2.harvard.edu
Subject   st: RE: Floating-point reals, hexadecimal and decimals
Date   Thu, 3 Jul 2003 10:38:03 -0400

yesterday I wrote,

> This is a Stata and Perl question.

In fact, much more Perl than Stata, but still a Stata problem.  Apologies if
anyone deems this to be a misuse of the list.

> I am generating a Perl module to read Stata data files and
> I need some clarification with regard to the conversion
> of floating-point numbers into decimal and hexadecimal values.
>
> <snip>
>
> when I try to write a missing value by 'packing' it
> from its hexadecimal representation, according to the
> following table (pasted from -help .dta-)
> 
>    V            value                HILO             LOHI
>    ---------------------------------------------------------------
> <snip>
>    .    +1.000000X+7f           7f000000          0000007f
>    .a   +1.001000X+7f           7f000800          0008007f
>    .b   +1.002000X+7f           7f001000          0010007f
>    .z   +1.01a000X+7f           7f00d000          00d0007f
>    ---------------------------------------------------------------
> 
> I don't get the expected results, e.g. if I try either
> 
>     syswrite DTA, pack("f", 0x0008007f), 4;
> or
>     syswrite DTA, pack("f", 0x7f000800), 4;
> 
> what gets written to DTA is F0070049 and 1000FE4E 
> respectively, not the
> 0008007F I expected .
> 
> Would anyone happen to know why I am having trouble with the 
> hex -> binary
> conversion?  Thanks in advance.


I found the solution.  The hex -> binary conversion wouldn't work yesterday
since by

     syswrite DTA, pack("f", 0x0008007f);

the hex string got converted to decimal prior to being packed as a binary
IEEE single-precision float.  The solution is to

	syswrite DTA, pack("H*", "0000007f");
	syswrite DTA, pack("H*", "0008007f");
	syswrite DTA, pack("H*", "0010007f");
	syswrite DTA, pack("H*", "00d0007f");

which properly maps missing values ., .a, .b, and .z to their binary values.
This conversion uses the Perl template character H which stands for
'hexadecimal string, high nybble first'.  This surprises me a little since I
thought I was feeding a *LOHI* hex string.  I thought the template character
'h' (low nybble first) would be the proper one.

At any rate, I presume that for portability, I should code

	syswrite DTA, pack("h*", "7f000000");
	syswrite DTA, pack("h*", "7f000800");
	syswrite DTA, pack("h*", "7f001000");
	syswrite DTA, pack("h*", "7f00d000");

for HILO system.  Comments are welcome.


Patrick Joly
joly.patrick@ic.gc.ca
pat.joly@utoronto.ca
*
*   For searches and help try:
*   http://www.stata.com/support/faqs/res/findit.html
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/



© Copyright 1996–2014 StataCorp LP   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index