From @mail.uunet.ca:beejay@micor Thu Apr 8 00:45:31 1993 Received: from calvin.sfasu.edu by umaxc.weeg.uiowa.edu (5.61.jnf/920629) on Thu, 8 Apr 93 00:44:55 -0500 id AA24933 with SMTP Received: from ghost.uunet.ca (uunet.ca) by calvin.sfasu.EDU with SMTP (5.59/25-eef) id AA29181; Thu, 8 Apr 93 00:37:20 CDT Return-Path: <@mail.uunet.ca:beejay@micor> Received: from ocunix by mail.uunet.ca with UUCP id <10462(4)>; Thu, 8 Apr 1993 01:36:15 -0400 Received: by micor.OCUnix.On.Ca (smail2.5) id AA19392; 8 Apr 93 00:23:22 EDT (Thu) To: hyperc-l@calvin.sfasu.edu Subject: Discoveries: floating point Date: Wed, 7 Apr 1993 20:23:20 -0400 Message-Id: <9304080023.AA19380@micor.OCUnix.On.Ca> From: beejay@micor.ocunix.on.ca (Basil Johnson) Status: R I have spent the better part of the week reading and reviewing the floating point package and I was still perplexed when I started writing to ask your help. During the process of writing, I discovered the answer to my questions and thought I'd share the problem and the discovery with you all. My test suite for a project I'm working on included the display of the following numbers: 123, 40304, 456789, 12.978 and 123456.789012. The first two numbers were easily handled with standard HyperC. It was obvious that 12.978 and 123456.789012 could be declared as type EXTENDED and assignment of constant would be Extended(12.978) and Extended(123456.789012). A look at the LOGTABLE example showed me that I should use fptostr() to format an EXTENDED variable. It worked. Is that all there is, I asked myself? Can't be! Why would the package have the others: Double(), Single etc,. I got Double(123456.789012) with cvdtox() and fptostr() to work when I eventually realized that a Double(xxx) assignment required a corresponding DOUBLE declaration. But I was stymied when handling the number 456789. None of the other succesful strtegies worked with it. After many fruitless attempts with COMP and LONG I decided to come to hyperc-l for help. Take the number, 456789 (0x06f855). My understanding of the literature is that the range for long int is 0 ... +/- 2.2E+9, so this is in the acceptable range. I should be able to declare it like this, I think: EXTENDED xtd; /* dest for cv?tox calls must be extended */ LONG 32bit_var; char buf[80]; 32bit_var = Long(456789); And to display it, I should do this: cvltox(&xtd, 32bit_var); /* first: convert long to extended */ fptostr(buf, xtd, 'x', 0, NO); /* convert extended to string */ /* fpType = eXtended; 0 dec places converted to 6 do NOt use exponent notation */ printf("%s\n", buf); /* print converted string */ I get a compilation error : "not a pointer" on the line: 32bit_var = Long(456789) So I change LONG 32bit_var to LONG *32bit_var and compile again. Again I get an error. This time, it is: _Long unresolved. On re-reading the docs for what must be at least the 20th time, I find a note that the preprocessor recognizes Extended, Double, Single and Comp. There is no mention of Long or Integer. I had passed over this subtle exclusion so many times before. This time I was looking for an answer to a specific problem. There is no warning about this anywhere although both are a part of the package. Lousy docs. The logtable example is an extremely simple one that doesn't touch the whole spectrum of the package. I give up on LONG for now. I try the same exercise using Comp(456789), replacing LONG with COMP, replacing cvltox with cvctox. That compiles without error. The display I get is: -1963.000000. When I looked into memory I see a string of 9 bytes (size of Comp): 558f ffff ffff ffff 00 What I expected to see for 456789 is 558f 0600 0000 0000 00 On looking at -1963, I realize what the number represents. 6 * 65536 = 393216 456789 - 393216 = 63573 (0xf855) 63573 - 65536 = -1963 So, except for the missing high word, the result makes sense. I try using Double(456789). Results are the same as with Comp. Back to the docs. I ferret out this piece of info. If the number does not contain any decimal point, then an exponent is required, else the number will be considered an integer value. ------- That explains why the low word is correct (0xf855) and suggests that ffff in the high word was a truncation, i.e. garbage. On using 456789. as the argument for Comp() and Double() and the appropriate cv?tox macro, I finally got the correct answers. That solved, back to investigating the LONG. Accepting that Long(xxxx) is not an valid assignment, I surmised that since the standard HyperC provides for int and HyperC itself uses an array of 2 longs to provide a 32 bit equivalent of LONG, perhaps the fpType I ought to use would be EXTENDED. That was the key. This is what worked finally. EXTENDED xtd; /* dest for cv?tox calls must be extended */ LONG 32bit_var; 32bit_var = Extended(456789.0); /* operand must have decimal point */ char buf[80]; And to display it, I should do this: cvltox(&xtd, 32bit_var); /* first: convert long to extended */ fptostr(buf, xtd, 'x', 0, NO); /* convert extended to string */ /* fpType = eXtended; 0 dec places converted to 6 do NOt use exponent notation */ printf("%s\n", buf); /* print converted string */ To convert the extended 32bit_var to hex, you use the function cvxtol and use a pointer to pick up and display the 4 bytes. Until the next discovery, Your sleuth, Basil (Sherlock) Johnson Basil Johnson UUCP: micor!beejay |Oh, Fate! ... Nepean, Ontario InterNet: |Such a stupid thing: CANADA K2B 8E9 beejay@micor.ocunix.on.ca |Command a bird to fly (613) 820-0804 |Then clip its wing!