Post Reply 
FORTH for the PC-G850(V)(S)
01-03-2023, 06:57 PM (This post was last modified: 01-04-2023 02:30 PM by robve.)
Post: #14
RE: FORTH for the PC-G850(V)(S)
(01-03-2023 03:32 AM)F-73P Wrote:  Did you write routines to convert between strings and floats? I've started writing string-to-double and double-to-string routines and it's quite challenging, requiring extended-precision arithmetic and tables.

Yes. For single precision floating point, that is.

I evaluated three strategies with tables. Because single precision floating point decimal exponents are limited to the +/-38 range, a full powers of 10 table is logical to use but an overkill. I found that a table with 12 entries saves memory and is sufficiently accurate, almost as accurate as a full table.

I've documented this in the mathr.asm assembly source and also in mathri.asm (same, but with inf/nan and signed zero) see the fpow10 routine:

Code:
;                 method                                   min bits   mean bits
;                 iterative multiplication by 10:           20.2439     23.4988
;                 iterative multiplication by 10**4:        21.3502     24.4916
;                 iterative multiplication by 10**5:        21.3243     24.5500
;                 iterative multiplication by 10**6:        21.3297     24.5937
;                 iterative multiplication by 10**7:        21.3253     24.5619
;                 iterative multiplication by 10**8:        21.3004     24.5260
;                 iterative multiplication by 10**10:       21.0809     24.4483
;                 iterative multiplication by 10**16:       20.7694     24.0836
;                 table lookup with  4 powers of 10:        21.4136     24.6670
;                 table lookup with  8 powers of 10:        21.9131     25.2981
;                 table lookup with  9 powers of 10:        21.8907     25.4628
;                 table lookup with 10 powers of 10:        22.0177     25.5388
;               * table lookup with 12 powers of 10:        22.0482     25.7529
;                 table lookup with 16 powers of 10:        22.0004     25.4073
;                 exponentiation by squaring from bottom:   22.0004     25.3867
;                 exponentiation by squaring from top:      22.0023     25.3830
;                 table lookup with 38 powers of 10:        exact       exact
;
;               * = selected and enabled for small code size and high accuracy

where "min bits" means the minimal number of bits guaranteed to be accurate -log(d)/log(2.0) with minimum d of relative errors e between x and y = fabs(x - y)/fabs(y), and "mean bits" means the number of bits accurate on average (relative error) in 10 million random samples: -log(a/SAMPLES)/log(2.0) with a the sum of relative errors. The mantissa has 24 bits. Note that summing relative errors can get over 25 "mean bits", which is when more cases are exact than have errors. I ran the tests in C code (DM me if you want this code).

The method selected (table of 12) is enabled with .if-.endif, while the others are disabled, but could be used. I would believe that with double precision floating point you could use a small table, perhaps as small as 12 but probably larger. Exponentiation by squaring is another option to keep the table small. See my assembly source code for the Z80 routines.

As you also point out, the powers of 10 tables are used by atof (string to float) and ftoa (float to string). The mathr.asm ftoa routine computes ((exponent - bias - 1) * 77 + 77 + 82) / 256 to estimate the decimal exponent given the biased binary exponent. I've seen this elsewhere, but I made an improvement to adjust with +82 to prevent underestimation. With double precision this will need work and more tweaking.

In the atof routine I used a 32 bit mantissa to multiply by 10 to maintain accuracy and produce a 24 bit mantissa from a string of digits without loss or precision up to 31 digits, with rounding to nearest ties to even when over 10 digits or so. For double precision, this needs a 64 bit mantissa.

Beware of pitfalls when parsing floats. Floats can be represented in many different ways, such as 1234567890E-45 and 0.0000000000123456789E45 for example. Rather obvious to look at, but the code should handle it.

I wrote the math code in less than a week in the evenings, but testing took another week or two to make sure there are no bugs and to make some tweaks. For example, I found that the round to nearest ties to even with "sticky bits" didn't work correctly, so I came up with a better way to implement this mechanism without requiring much code or using Z80 registers which I can't, since they are already all in use.

There is a lot more I could comment on. If you have questions, let me know in your reply or DM me.

- Rob

"I count on old friends" -- HP 71B,Prime|Ti VOY200,Nspire CXII CAS|Casio fx-CG50...|Sharp PC-G850,E500,2500,1500,14xx,13xx,12xx...
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
FORTH for the PC-G850(V)(S) - robve - 11-06-2022, 01:56 PM
RE: FORTH for the PC-G850(V)(S) - robve - 11-08-2022, 09:23 PM
RE: FORTH for the PC-G850(V)(S) - Sukiari - 11-09-2022, 07:45 PM
RE: FORTH for the PC-G850(V)(S) - robve - 11-10-2022, 09:36 PM
RE: FORTH for the PC-G850(V)(S) - xerxes - 11-11-2022, 01:55 AM
RE: FORTH for the PC-G850(V)(S) - robve - 11-12-2022, 12:28 AM
RE: FORTH for the PC-G850(V)(S) - robve - 11-12-2022, 06:26 PM
RE: FORTH for the PC-G850(V)(S) - robve - 11-13-2022, 10:15 PM
RE: FORTH for the PC-G850(V)(S) - robve - 11-14-2022, 07:35 PM
RE: FORTH for the PC-G850(V)(S) - robve - 11-29-2022, 07:56 PM
RE: FORTH for the PC-G850(V)(S) - robve - 12-07-2022, 03:07 AM
RE: FORTH for the PC-G850(V)(S) - robve - 01-01-2023, 05:45 PM
RE: FORTH for the PC-G850(V)(S) - F-73P - 01-03-2023, 03:32 AM
RE: FORTH for the PC-G850(V)(S) - robve - 01-03-2023 06:57 PM
RE: FORTH for the PC-G850(V)(S) - F-73P - 01-05-2023, 07:52 AM
RE: FORTH for the PC-G850(V)(S) - robve - 05-20-2023, 11:11 PM
RE: FORTH for the PC-G850(V)(S) - robve - 07-31-2023, 01:53 AM



User(s) browsing this thread: 1 Guest(s)