Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #135242 > unrolled thread
| Started by | Krishna Myneni <krishna.myneni@ccreweb.org> |
|---|---|
| First post | 2026-07-20 09:48 -0500 |
| Last post | 2026-08-24 18:55 -0500 |
| Articles | 20 on this page of 29 — 6 participants |
Back to article view | Back to comp.lang.forth
kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-07-20 09:48 -0500
Re: kForth-Win32 fix for decimal string to double float conversion albert@SPENARNC.XS4ALL.NL - 2026-07-21 11:40 +0200
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-07-21 06:20 -0500
Re: kForth-Win32 fix for decimal string to double float conversion albert@SPENARNC.XS4ALL.NL - 2026-07-25 16:08 +0200
Re: kForth-Win32 fix for decimal string to double float conversion peter <peter.noreply@tin.it> - 2026-07-25 17:07 +0200
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-07-25 13:22 -0500
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-07-25 13:30 -0500
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-07-25 13:17 -0500
Re: kForth-Win32 fix for decimal string to double float conversion dxf <dxforth@gmail.com> - 2026-07-26 13:15 +1000
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-07-26 07:18 -0500
Re: kForth-Win32 fix for decimal string to double float conversion dxf <dxforth@gmail.com> - 2026-07-31 14:54 +1000
Re: kForth-Win32 fix for decimal string to double float conversion anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-07-31 08:35 +0000
Re: kForth-Win32 fix for decimal string to double float conversion albert@spenarnc.xs4all.nl - 2026-07-31 12:05 +0200
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-07-31 07:54 -0500
Re: kForth-Win32 fix for decimal string to double float conversion anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-07-31 16:55 +0000
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-07-31 14:40 -0500
Re: kForth-Win32 fix for decimal string to double float conversion anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-08-01 08:23 +0000
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-08-01 06:42 -0500
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-07-21 11:30 -0500
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-07-21 14:47 -0500
Re: kForth-Win32 fix for decimal string to double float conversion albert@SPENARNC.XS4ALL.NL - 2026-07-25 23:42 +0200
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-07-25 18:47 -0500
Re: kForth-Win32 fix for decimal string to double float conversion albert@SPENARNC.XS4ALL.NL - 2026-07-26 13:11 +0200
Re: kForth-Win32 fix for decimal string to double float conversion albert@SPENARNC.XS4ALL.NL - 2026-07-26 13:22 +0200
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-07-26 07:23 -0500
Re: kForth-Win32 fix for decimal string to double float conversion albert@SPENARNC.XS4ALL.NL - 2026-07-26 20:13 +0200
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-07-27 12:20 -0500
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-08-11 07:24 -0500
Re: kForth-Win32 fix for decimal string to double float conversion Krishna Myneni <krishna.myneni@ccreweb.org> - 2026-08-24 18:55 -0500
Page 1 of 2 [1] 2 Next page →
| From | Krishna Myneni <krishna.myneni@ccreweb.org> |
|---|---|
| Date | 2026-07-20 09:48 -0500 |
| Subject | kForth-Win32 fix for decimal string to double float conversion |
| Message-ID | <113lcfk$18opt$1@dont-email.me> |
I recently fixed a problem with kForth-Win32's conversion of decimal strings to IEEE double precision floats e.g., with rounding mode set to round nearest (with ties to eve), the string "1.000 000 000 000 000 111 022 302 462 515 654 042 363 166 809 082 031 251 e0" (spaces added for clarity) converted to the IEEE 64-bit binary pattern (shown in hex, high-dword low- dword) 3ff00000 00000000 representing the exact number 1.000 ... instead of converting to the nearest representable IEEE 754 double precision number, 3ff00000 00000001 which has the value 1.000 000 000 000 000 222 044 604 925 031 308 084 726 333 618 164 062 500 Thus, the following Forth code should behave as follows: 17 set-precision ok 1.000000000000000111022302462515654042363166809082031251e0 fs. 1.0000000000000002e+00 ok instead of printing 1.000000000000000e+00 Note that this is not an output conversion problem with the word "FS." but an interpreter input conversion problem for the entered floating point value. Using double number arithmetic on a 64-bit Forth system, you may easily verify that the correct round to nearest representable floating point value is the one represented by the binary pattern 3ff00000 00000001 , rather than to the exactly representable value of 1.000.... (pattern 3ff00000 00000000): #222 044 604 925 031 308 084 726 333 618 164 062 500. #111 022 302 462 515 654 042 363 166 809 082 031 251. D- UD. which prints 111 022 302 462 515 654 042 363 166 809 082 031 249 and is smaller than the distance between 1.000 000 000 000 000 111 022 302 462 515 654 042 363 166 809 082 031 251e0 and the exactly representable 1.000 ... Be sure to remove spaces between the digits in the code above. The Problem: ----------- This is a quality of implementation issue in the decimal string to floating point conversion implemented in the C library function, strtod(), for the Digital Mars C/C++ compiler. The conversion is not simple, and has been studied extensively by a number of people. Of particular note is the following paper, "Correctly Rounded Binary-Decimal and Decimal-Binary Conversions," David M. Gay, Numerical Analysis Manuscript 90-10, AT&T Bell Laboratories, 30 November 1990. and the corresponding code, dtoa.c, link below, which provides a high-quality strtod() replacement function for decimal string to binary floating point conversions, as well as the inverse function, dtoa(). https://netlib.org/fp/dtoa.c The kForth system test code, fpio-test.4th, may be used to identify problems with decimal string conversion to IEEE double floats in other Forth systems. The test file may be found at the link below. https://github.com/mynenik/kForth-Win32/blob/master/forth-src/system-test/fpio-test.4th The Fix: ------- There are several approaches to doing the conversion correctly (see the paper mentioned above, and the references therein). The replacement strtod() function in dtoa.c uses its built-in big integer arithmetic to do the conversions, and this library is apparently used in languages like python and Java. kForth-Win32, as of version 2.5.5, uses the strtod() function from dtoa.c. Previous versions of kForth-Win32 did not pass all tests from fpio-test.4th. Version 2.5.5 passes all of the tests. The Linux versions of kForth are not affected since GCC fixed their conversions a while back. Why does it matter?: ------------------- Without proper rounding to nearest representable double-precision binary value, some computational cases can suffer significant reduction in accuracy. Examples are range reduction for large value arguments to trigonometric functions (sin, cos, tan) and solving systems of nonlinear differential equations with sensitivity to initial conditions. -- Krishna Myneni
[toc] | [next] | [standalone]
| From | albert@SPENARNC.XS4ALL.NL |
|---|---|
| Date | 2026-07-21 11:40 +0200 |
| Message-ID | <nnd$10021294$12a53193@9ed426c01832dcf1> |
| In reply to | #135242 |
Krishna Myneni <krishna.myneni@ccreweb.org> wrote: > I recently fixed a problem with kForth-Win32's conversion of decimal > strings to IEEE double precision floats e.g., with rounding mode set to > round nearest (with ties to eve), the string > > "1.000 000 000 000 000 111 022 302 462 515 654 042 363 166 809 082 031 > 251 e0" (spaces added for clarity) > > converted to the IEEE 64-bit binary pattern (shown in hex, high-dword > low- dword) > > 3ff00000 00000000 > > representing the exact number 1.000 ... > > instead of converting to the nearest representable IEEE 754 double > precision number, > > 3ff00000 00000001 > > which has the value > > 1.000 000 000 000 000 222 044 604 925 031 308 084 726 333 618 164 062 500 > > Thus, the following Forth code should behave as follows: > > 17 set-precision > ok > 1.000000000000000111022302462515654042363166809082031251e0 fs. > 1.0000000000000002e+00 ok > > instead of printing 1.000000000000000e+00 > > Note that this is not an output conversion problem with the word "FS." > but an interpreter input conversion problem for the entered floating > point value. > > Using double number arithmetic on a 64-bit Forth system, you may easily > verify that the correct round to nearest representable floating point > value is the one represented by the binary pattern 3ff00000 00000001 , > rather than to the exactly representable value of 1.000.... (pattern > 3ff00000 00000000): If a number contains an exponent character, denoting a floating point, I convert this floating point number from the end. This had nothing to do with 32/64 bit system as it runs in the floating point 8087. In this case I remember the exponent first. start with 0, add 1 , divide by 10 add 5 , 5 divide by 10 .. decimal point, remember the place. The initial floating point number is 1/10 , the rounding mode doesn't matter much, because a host of larger numbers have been added. 1.000000000000000111022302462515654042363166809082031251E0 FS. 1.000000000000000110E0 > > -- > Krishna Myneni > > > > > > -- The glass is half empty. There is no such thing as a free world. This is the first day of the end of your life. If you can't beat them, ... too bad.
[toc] | [prev] | [next] | [standalone]
| From | Krishna Myneni <krishna.myneni@ccreweb.org> |
|---|---|
| Date | 2026-07-21 06:20 -0500 |
| Message-ID | <113nkmm$1u1in$1@dont-email.me> |
| In reply to | #135244 |
On 7/21/26 04:40, albert@SPENARNC.XS4ALL.NL wrote: > Krishna Myneni <krishna.myneni@ccreweb.org> wrote: ... >> >> Using double number arithmetic on a 64-bit Forth system, you may easily >> verify that the correct round to nearest representable floating point >> value is the one represented by the binary pattern 3ff00000 00000001 , >> rather than to the exactly representable value of 1.000.... (pattern >> 3ff00000 00000000): > > If a number contains an exponent character, denoting a floating point, > I convert this floating point number from the end. This had nothing > to do with 32/64 bit system as it runs in the floating point 8087. > In this case I remember the exponent first. > start with 0, > add 1 , divide by 10 > add 5 , 5 divide by 10 > .. > decimal point, remember the place. > > The initial floating point number is 1/10 , the rounding mode > doesn't matter much, because a host of larger numbers have been added. > > 1.000000000000000111022302462515654042363166809082031251E0 FS. > 1.000000000000000110E0 > ... I think you misunderstood the referenced paragraph. It has to do with checking the conversion to see which of the adjacent representable double precision numbers is the nearest one when the rounding mode is set to nearest. It is possible to do this with integer arithmetic but one needs double length 64-bit cell numbers to do it for the examples given above. -- KM
[toc] | [prev] | [next] | [standalone]
| From | albert@SPENARNC.XS4ALL.NL |
|---|---|
| Date | 2026-07-25 16:08 +0200 |
| Message-ID | <nnd$245e5ae0$2ade0865@74903abd065dd450> |
| In reply to | #135245 |
Krishna Myneni <krishna.myneni@ccreweb.org> wrote: > On 7/21/26 04:40, albert@SPENARNC.XS4ALL.NL wrote: >> Krishna Myneni <krishna.myneni@ccreweb.org> wrote: > ... >>> >>> Using double number arithmetic on a 64-bit Forth system, you may easily >>> verify that the correct round to nearest representable floating point >>> value is the one represented by the binary pattern 3ff00000 00000001 , >>> rather than to the exactly representable value of 1.000.... (pattern >>> 3ff00000 00000000): >> >> If a number contains an exponent character, denoting a floating point, >> I convert this floating point number from the end. This had nothing >> to do with 32/64 bit system as it runs in the floating point 8087. >> In this case I remember the exponent first. >> start with 0, >> add 1 , divide by 10 >> add 5 , 5 divide by 10 >> .. >> decimal point, remember the place. >> >> The initial floating point number is 1/10 , the rounding mode >> doesn't matter much, because a host of larger numbers have been added. >> >> 1.000000000000000111022302462515654042363166809082031251E0 FS. >> 1.000000000000000110E0 >> > ... > > I think you misunderstood the referenced paragraph. It has to do with > checking the conversion to see which of the adjacent representable > double precision numbers is the nearest one when the rounding mode is > set to nearest. It is possible to do this with integer arithmetic but > one needs double length 64-bit cell numbers to do it for the examples > given above. If you set rounding mode to nearest, you expect to get the nearest result ??? Default is round to nearest. If you start at the end with the conversion all the intermediate results are round to nearest. You process 60 digits and shift 40 digits into oblivion. The last digit is 1. If this is the 60th decimal it is divided by 10 sixty times. There is nothing left of the poor 1, let alone of its rounding errors. I think there is no need to check the end result with my method, unless I'm thoroughly mistaken. Groetjes Albert P.S. I do not buy that 10e100 FSIN becomes any better if you do the range reduction with utmost precision. > > -- > KM > -- The glass is half empty. There is no such thing as a free world. This is the first day of the end of your life. If you can't beat them, ... too bad.
[toc] | [prev] | [next] | [standalone]
| From | peter <peter.noreply@tin.it> |
|---|---|
| Date | 2026-07-25 17:07 +0200 |
| Message-ID | <20260725170716.00005ebb@tin.it> |
| In reply to | #135263 |
On Sat, 25 Jul 2026 16:08:35 +0200 albert@SPENARNC.XS4ALL.NL wrote: > Krishna Myneni <krishna.myneni@ccreweb.org> wrote: > > On 7/21/26 04:40, albert@SPENARNC.XS4ALL.NL wrote: > >> Krishna Myneni <krishna.myneni@ccreweb.org> wrote: > > ... > >>> > >>> Using double number arithmetic on a 64-bit Forth system, you may easily > >>> verify that the correct round to nearest representable floating point > >>> value is the one represented by the binary pattern 3ff00000 00000001 , > >>> rather than to the exactly representable value of 1.000.... (pattern > >>> 3ff00000 00000000): > >> > >> If a number contains an exponent character, denoting a floating point, > >> I convert this floating point number from the end. This had nothing > >> to do with 32/64 bit system as it runs in the floating point 8087. > >> In this case I remember the exponent first. > >> start with 0, > >> add 1 , divide by 10 > >> add 5 , 5 divide by 10 > >> .. > >> decimal point, remember the place. > >> > >> The initial floating point number is 1/10 , the rounding mode > >> doesn't matter much, because a host of larger numbers have been added. > >> > >> 1.000000000000000111022302462515654042363166809082031251E0 FS. > >> 1.000000000000000110E0 > >> > > ... > > > > I think you misunderstood the referenced paragraph. It has to do with > > checking the conversion to see which of the adjacent representable > > double precision numbers is the nearest one when the rounding mode is > > set to nearest. It is possible to do this with integer arithmetic but > > one needs double length 64-bit cell numbers to do it for the examples > > given above. > > If you set rounding mode to nearest, you expect to get the > nearest result ??? > > Default is round to nearest. > If you start at the end with the conversion all the intermediate results > are round to nearest. > You process 60 digits and shift 40 digits into oblivion. > The last digit is 1. If this is the 60th decimal it is divided by 10 sixty > times. There is nothing left of the poor 1, let alone of its rounding > errors. > > I think there is no need to check the end result with my method, > unless I'm thoroughly mistaken. > > Groetjes Albert > > P.S. > I do not buy that 10e100 FSIN becomes any better if you do the > range reduction with utmost precision. > so what do you get for 10e100 fsin ? In my system I get: (using 64 bit floats) 10e100 fsin f. 0.995717064571709700 or to avoid the conversion to decimal 10e100 fsin fh. 0x1.FDCEA088CF298p-1 BR Peter
[toc] | [prev] | [next] | [standalone]
| From | Krishna Myneni <krishna.myneni@ccreweb.org> |
|---|---|
| Date | 2026-07-25 13:22 -0500 |
| Message-ID | <1142usd$1m890$2@dont-email.me> |
| In reply to | #135264 |
On 7/25/26 10:07, peter wrote: > On Sat, 25 Jul 2026 16:08:35 +0200 > albert@SPENARNC.XS4ALL.NL wrote: > ... >> I do not buy that 10e100 FSIN becomes any better if you do the >> range reduction with utmost precision. >> > so what do you get for 10e100 fsin ? > > In my system I get: (using 64 bit floats) > > 10e100 fsin f. 0.995717064571709700 > > or to avoid the conversion to decimal > > 10e100 fsin fh. 0x1.FDCEA088CF298p-1 > > Using the x87 FSIN instruction with this argument, I obtain NAN. -- KM
[toc] | [prev] | [next] | [standalone]
| From | Krishna Myneni <krishna.myneni@ccreweb.org> |
|---|---|
| Date | 2026-07-25 13:30 -0500 |
| Message-ID | <1142vc4$1m890$3@dont-email.me> |
| In reply to | #135267 |
On 7/25/26 13:22, Krishna Myneni wrote: > On 7/25/26 10:07, peter wrote: >> On Sat, 25 Jul 2026 16:08:35 +0200 >> albert@SPENARNC.XS4ALL.NL wrote: >> > ... >>> I do not buy that 10e100 FSIN becomes any better if you do the >>> range reduction with utmost precision. >>> >> so what do you get for 10e100 fsin ? >> >> In my system I get: (using 64 bit floats) >> >> 10e100 fsin f. 0.995717064571709700 >> >> or to avoid the conversion to decimal >> >> 10e100 fsin fh. 0x1.FDCEA088CF298p-1 >> >> > Using the x87 FSIN instruction with this argument, I obtain NAN. > Sorry, that was the FSINCOS instruction which gave a NAN. FSIN instruction gives a ridiculous answer with an argument of 10E100, way outside of the range of -1 to 1. -- KM
[toc] | [prev] | [next] | [standalone]
| From | Krishna Myneni <krishna.myneni@ccreweb.org> |
|---|---|
| Date | 2026-07-25 13:17 -0500 |
| Message-ID | <1142uj0$1m890$1@dont-email.me> |
| In reply to | #135263 |
On 7/25/26 09:08, albert@SPENARNC.XS4ALL.NL wrote: > Krishna Myneni <krishna.myneni@ccreweb.org> wrote: >> On 7/21/26 04:40, albert@SPENARNC.XS4ALL.NL wrote: >>> Krishna Myneni <krishna.myneni@ccreweb.org> wrote: >> ... >>>> >>>> Using double number arithmetic on a 64-bit Forth system, you may easily >>>> verify that the correct round to nearest representable floating point >>>> value is the one represented by the binary pattern 3ff00000 00000001 , >>>> rather than to the exactly representable value of 1.000.... (pattern >>>> 3ff00000 00000000): >>> >>> If a number contains an exponent character, denoting a floating point, >>> I convert this floating point number from the end. This had nothing >>> to do with 32/64 bit system as it runs in the floating point 8087. >>> In this case I remember the exponent first. >>> start with 0, >>> add 1 , divide by 10 >>> add 5 , 5 divide by 10 >>> .. >>> decimal point, remember the place. >>> >>> The initial floating point number is 1/10 , the rounding mode >>> doesn't matter much, because a host of larger numbers have been added. >>> >>> 1.000000000000000111022302462515654042363166809082031251E0 FS. >>> 1.000000000000000110E0 >>> >> ... >> >> I think you misunderstood the referenced paragraph. It has to do with >> checking the conversion to see which of the adjacent representable >> double precision numbers is the nearest one when the rounding mode is >> set to nearest. It is possible to do this with integer arithmetic but >> one needs double length 64-bit cell numbers to do it for the examples >> given above. > > If you set rounding mode to nearest, you expect to get the > nearest result ??? The nearest result to within 1 ulp which can be represented with 53 bit significand. Not all C libraries provide a string to double float conversion which actually rounds to the nearest representable IEEE double precision float for all cases. 32-bit GCC's libraries also failed to convert to the nearest prior to sometime in the early 2000s. It is true for the last version of the libc supplied with the Digital Mars C/C++ (formerly Symantec C/C++) compiler for 32-bit Windows. Forth systems based on those C libraries, using the built-in strtod() or atof() functions for converting strings to double precision floats will fail on some test cases. This is what the tests in fpio-test.4th aim to catch. > > Default is round to nearest. > If you start at the end with the conversion all the intermediate results > are round to nearest. > You process 60 digits and shift 40 digits into oblivion. > The last digit is 1. If this is the 60th decimal it is divided by 10 sixty > times. There is nothing left of the poor 1, let alone of its rounding > errors. > > I think there is no need to check the end result with my method, > unless I'm thoroughly mistaken. > Run the fpio-tests for your input conversions to check. In your prior message, you showed me an output which is not even representable in double precision. > Groetjes Albert > > P.S. > I do not buy that 10e100 FSIN becomes any better if you do the > range reduction with utmost precision. > If you don't believe it, try providing such large arguments to the FSIN FCOS or FTAN instructions of the x87 FPU and see for yourself. -- Krishna
[toc] | [prev] | [next] | [standalone]
| From | dxf <dxforth@gmail.com> |
|---|---|
| Date | 2026-07-26 13:15 +1000 |
| Message-ID | <6a657bd2$1@news.ausics.net> |
| In reply to | #135266 |
On 26/07/2026 4:17 am, Krishna Myneni wrote: > ... > Run the fpio-tests for your input conversions to check. In your prior message, you showed me an output which is not even representable in double precision. FWIW running your test on my F87 EXT prec system produced 0 errors; while F87 DBL prec resulted in 18 errors. I may try re-writing my input routine to parse from the other end but my suspicion is it will be the same. It may avoid having to SET-NEAR but likely that's all. The IEEE spec for exact conversion was always going to be a high bar. If one must have that, I'd rather use an EXT prec system and rename DF@ DF! to F@ F! .
[toc] | [prev] | [next] | [standalone]
| From | Krishna Myneni <krishna.myneni@ccreweb.org> |
|---|---|
| Date | 2026-07-26 07:18 -0500 |
| Message-ID | <1144tts$2bpng$1@dont-email.me> |
| In reply to | #135272 |
On 7/25/26 22:15, dxf wrote: > On 26/07/2026 4:17 am, Krishna Myneni wrote: >> ... >> Run the fpio-tests for your input conversions to check. In your prior message, you showed me an output which is not even representable in double precision. > > FWIW running your test on my F87 EXT prec system produced 0 errors; > while F87 DBL prec resulted in 18 errors. > That is expected. If you use 80-bit Extended Precision and then convert to 64-bit Double Precision, they should match. However, the tests in fpio-test.4th do not guarantee that the decimal string conversion is good to within 1 ulp for all 64 bits of the significand for the 80-bit format. The tests are specific to double precision format conversions. > I may try re-writing my input routine to parse from the other end but > my suspicion is it will be the same. It may avoid having to SET-NEAR > but likely that's all. > > The IEEE spec for exact conversion was always going to be a high bar. > If one must have that, I'd rather use an EXT prec system and rename > DF@ DF! to F@ F! . > David Gay's code, dtoa.c, is available to use for anyone interested in doing accurate decimal string to IEEE double precision format conversions and vice-versa. Your executable may grow by about 30--40K. I believe it supports 16 bit systems, but you may have to check. -- Krishna
[toc] | [prev] | [next] | [standalone]
| From | dxf <dxforth@gmail.com> |
|---|---|
| Date | 2026-07-31 14:54 +1000 |
| Message-ID | <6a6c2aa1$1@news.ausics.net> |
| In reply to | #135275 |
On 26/07/2026 10:18 pm, Krishna Myneni wrote: > On 7/25/26 22:15, dxf wrote: >> On 26/07/2026 4:17 am, Krishna Myneni wrote: >>> ... >>> Run the fpio-tests for your input conversions to check. In your prior message, you showed me an output which is not even representable in double precision. >> >> FWIW running your test on my F87 EXT prec system produced 0 errors; >> while F87 DBL prec resulted in 18 errors. >> > > That is expected. If you use 80-bit Extended Precision and then convert to 64-bit Double Precision, they should match. However, the tests in fpio-test.4th do not guarantee that the decimal string conversion is good to within 1 ulp for all 64 bits of the significand for the 80-bit format. The tests are specific to double precision format conversions. > > >> I may try re-writing my input routine to parse from the other end but >> my suspicion is it will be the same. It may avoid having to SET-NEAR >> but likely that's all. >> >> The IEEE spec for exact conversion was always going to be a high bar. >> If one must have that, I'd rather use an EXT prec system and rename >> DF@ DF! to F@ F! . >> > > David Gay's code, dtoa.c, is available to use for anyone interested in doing accurate decimal string to IEEE double precision format conversions and vice-versa. Your executable may grow by about 30--40K. I believe it supports 16 bit systems, but you may have to check. I was aware of that solution though not the extent of the cost. Considering my entire forth runtime library is only 9K (3K being the f/p) it's quite a price to pay to achieve IEEE compliance. I've always wondered what possessed IEEE to specify a conversion that exceeded the ability of the intrinsic precision to readily provide. I notice forths that employ the Intel FPU have largely abandoned IEEE's double precision, instead opting for the internal 10-byte format. None of those AFAIK has made any attempt to achieve exact I/O conversion down to the last bit. I can fully appreciate their choice. Equally so, C-based forths that need only call in an existing library.
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2026-07-31 08:35 +0000 |
| Message-ID | <2026Jul31.103534@mips.complang.tuwien.ac.at> |
| In reply to | #135284 |
dxf <dxforth@gmail.com> writes:
>None of those AFAIK
>has made any attempt to achieve exact I/O conversion down to the last bit. I
>can fully appreciate their choice. Equally so, C-based forths that need only
>call in an existing library.
Gforth's REPRESENT calls glibc's ecvt_r(), and that produces an exact
representation of the number in decimal, if you give it a buffer with
enough size. A few days before the present thread started, I had
developed E.EXACT, which prints every digit in the exact decimal
representation of a binary FP number.
As you will see below, the exact representation can be longer than one
may want. For IEEE double-precision (aka binary64) numbers, the exact
numbers can have around
5e flog 1024e 53e f+ f* f.
i.e., 753 digits, while for 80387 80-bit numbers, the exact
representation can have around
5e flog 16384e 63e f+ f* f.
i.e., 11496 digits.
So, as a compromise between length and exactness, people tend to
prefer numbers that are close, but not exact. In particular, one can
use the shortest number that, when converted to binary, results in the
same number that one wants to convert to decimal. That needs at most
around 16 digits for IEEE double-precision numbers, and 20 digits for
80387 80-bit numbers. I plan to do that kind of conversion when I get
the time.
Here are the results for current E.EXACT:
0.1e e.exact \ .1000000000000000055511151231257827021181583404541015625e
\ smallest r>0, with 64-bit cells and 64-bit FP.
1 pad ! pad f@ cr e.exact \ output on the next line:
.4940656458412465441765687928682213723650598026143247644255856825006755072702087518652998363616359923797965646954457177309266567103559397963987747960107818781263007131903114045278458171678489821036887186360569987307230500063874091535649843873124733972731696151400317153853980741262385655911710266585566867681870395603106249319452715914924553293054565444011274801297099995419319894090804165633245247571478690147267801593552386115501348035264934720193790268107107491703332226844753335720832431936092382893458368060106011506169809753078342277318329247904982524730776375927247874656084778203734469699533647017972677717585125660551199131504891101451037862738167250955837389733598993664809941164205702637090279242767544565229087538682506419718265533447265625e-323
- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: https://forth-standard.org/
EuroForth 2026 CFP: http://www.euroforth.org/ef26/cfp.html
[toc] | [prev] | [next] | [standalone]
| From | albert@spenarnc.xs4all.nl |
|---|---|
| Date | 2026-07-31 12:05 +0200 |
| Message-ID | <nnd$6f47131d$698f478e@e57a18800d1310c2> |
| In reply to | #135285 |
In article <2026Jul31.103534@mips.complang.tuwien.ac.at>, Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote: >dxf <dxforth@gmail.com> writes: >>None of those AFAIK >>has made any attempt to achieve exact I/O conversion down to the last bit. I >>can fully appreciate their choice. Equally so, C-based forths that need only >>call in an existing library. > >Gforth's REPRESENT calls glibc's ecvt_r(), and that produces an exact >representation of the number in decimal, if you give it a buffer with >enough size. A few days before the present thread started, I had >developed E.EXACT, which prints every digit in the exact decimal >representation of a binary FP number. That trick doesn't work with base 3. It is by virtue of the fact that binary digit can be represented in base 10 which contains a factor 2. > >As you will see below, the exact representation can be longer than one >may want. For IEEE double-precision (aka binary64) numbers, the exact >numbers can have around > >5e flog 1024e 53e f+ f* f. > >i.e., 753 digits, while for 80387 80-bit numbers, the exact >representation can have around > >5e flog 16384e 63e f+ f* f. > >i.e., 11496 digits. It is obvious that switching to hexadecimal saves quite a few digits. 5E0 FLOG 1024E0 53E0 F+ F* S[ ] OK HEX FDUP 20 F.R 2.F0CA6AF7444F09980000000000000000_2 The big win is that the exponent is that 2^-100 is not artificially presented in decimal. The zeroes show that at all times a finite presentation is possible to convert back exactly. S[ ] OK 2.F0CA6AF7444F09980000000000000000_2 S[ ] OK F= S[ -1 ] OK At Shell there was communication from lisp (analysing) monsters to my group geological modelling (c FORTRAN). The numbers were communicated in ascii form. There was some discussion how much digits where needed, but these where physical measurements, so there was a real answer. [ unlike range reduction for sin(1E100). ] >as a compromise between length and exactness, people tend to >prefer numbers that are close, but not exact. In particular, one can >use the shortest number that, when converted to binary, results in the >same number that one wants to convert to decimal. That needs at most >around 16 digits for IEEE double-precision numbers, and 20 digits for >80387 80-bit numbers. I plan to do that kind of conversion when I get >the time. > >Here are the results for current E.EXACT: > >0.1e e.exact \ .1000000000000000055511151231257827021181583404541015625e >\ smallest r>0, with 64-bit cells and 64-bit FP. >1 pad ! pad f@ cr e.exact \ output on the next line: >.4940656458412465441765687928682213723650598026143247644255856825006755072702087518652998363616359923797965646954457177309266567103559397963987747960107818781263007131903114045278458171678489821036887186360569987307230500063874091535649843873124733972731696151400317153853980741262385655911710266585566867681870395603106249319452715914924553293054565444011274801297099995419319894090804165633245247571478690147267801593552386115501348035264934720193790268107107491703332226844753335720832431936092382893458368060106011506169809753078342277318329247904982524730776375927247874656084778203734469699533647017972677717585125660551199131504891101451037862738167250955837389733598993664809941164205702637090279242767544565229087538682506419718265533447265625e-323 Wow! > >- anton >-- >M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html >comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html > New standard: https://forth-standard.org/ >EuroForth 2026 CFP: http://www.euroforth.org/ef26/cfp.html -- The Chinese government is satisfied with its military superiority over USA. The next 5 year plan has as primary goal to advance life expectancy over 80 years, like Western Europe.
[toc] | [prev] | [next] | [standalone]
| From | Krishna Myneni <krishna.myneni@ccreweb.org> |
|---|---|
| Date | 2026-07-31 07:54 -0500 |
| Message-ID | <114i5tf$2nqra$1@dont-email.me> |
| In reply to | #135285 |
On 7/31/26 03:35, Anton Ertl wrote: > dxf <dxforth@gmail.com> writes: >> None of those AFAIK >> has made any attempt to achieve exact I/O conversion down to the last bit. I >> can fully appreciate their choice. Equally so, C-based forths that need only >> call in an existing library. > > Gforth's REPRESENT calls glibc's ecvt_r(), and that produces an exact > representation of the number in decimal, if you give it a buffer with > enough size. A few days before the present thread started, I had > developed E.EXACT, which prints every digit in the exact decimal > representation of a binary FP number. > ... Are you using an existing big number arithmetic package or did you roll your own? -- Krishna
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2026-07-31 16:55 +0000 |
| Message-ID | <2026Jul31.185552@mips.complang.tuwien.ac.at> |
| In reply to | #135288 |
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
>On 7/31/26 03:35, Anton Ertl wrote:
>> Gforth's REPRESENT calls glibc's ecvt_r(),
Correction: Gforth's REPRESENT calls ecvt_r(), and if that is provided
by a not-too-old glibc, the following holds:
>> and that produces an exact
>> representation of the number in decimal, if you give it a buffer with
>> enough size. A few days before the present thread started, I had
>> developed E.EXACT, which prints every digit in the exact decimal
>> representation of a binary FP number.
>> ...
>
>Are you using an existing big number arithmetic package or did you roll
>your own?
Neither. I just give a buffer with length 800 (enough for a
double-precision mantissa) to REPRESENT, and the ecvt_r()
implementation produces the decimal string representation of the
mantissa.
- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: https://forth-standard.org/
EuroForth 2026 CFP: http://www.euroforth.org/ef26/cfp.html
[toc] | [prev] | [next] | [standalone]
| From | Krishna Myneni <krishna.myneni@ccreweb.org> |
|---|---|
| Date | 2026-07-31 14:40 -0500 |
| Message-ID | <114itnh$3130h$1@dont-email.me> |
| In reply to | #135289 |
On 7/31/26 11:55, Anton Ertl wrote: > Krishna Myneni <krishna.myneni@ccreweb.org> writes: >> On 7/31/26 03:35, Anton Ertl wrote: >>> Gforth's REPRESENT calls glibc's ecvt_r(), > > Correction: Gforth's REPRESENT calls ecvt_r(), and if that is provided > by a not-too-old glibc, the following holds: > >>> and that produces an exact >>> representation of the number in decimal, if you give it a buffer with >>> enough size. A few days before the present thread started, I had >>> developed E.EXACT, which prints every digit in the exact decimal >>> representation of a binary FP number. >>> ... >> >> Are you using an existing big number arithmetic package or did you roll >> your own? > > Neither. I just give a buffer with length 800 (enough for a > double-precision mantissa) to REPRESENT, and the ecvt_r() > implementation produces the decimal string representation of the > mantissa. > glibc must have its own big number functions. The code dtoa.c by David Gay contains a limited set of big number arithmetic functions, needed to do decimal string to binary conversions and the other way around. Conversion code in Forth for both directions should be possible to write using the FSL big number arithmetic package, big.4th. -- Krishna
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2026-08-01 08:23 +0000 |
| Message-ID | <2026Aug1.102319@mips.complang.tuwien.ac.at> |
| In reply to | #135290 |
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
>glibc must have its own big number functions.
That's certainly possible.
>Conversion code in Forth for both directions should be possible to write
>using the FSL big number arithmetic package, big.4th.
Early in the Gforth project I thought about implementing string-to-FP
and FP-to-string conversion myself, remembering the to papers about
theses topics in the PLDI 1990 proceedings. Then I looked at the
papers and found that these topics are very complicated, and need a
complicated implementation, and decided to spend my time on other
things.
In the meantime, other papers have been published on the topic, and
maybe some of the complications have been eliminated, but I have not
looked. For now standing on the shoulders of the libc developers is
good enough for me. A student of mine wrote an overview paper of four
FP-to-string algorithms
<http://www.complang.tuwien.ac.at/Bachelorarbeiten/orlov23.pdf>; it's
in German, but the last page references the original papers, which you
may find interesting.
- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: https://forth-standard.org/
EuroForth 2026 CFP: http://www.euroforth.org/ef26/cfp.html
[toc] | [prev] | [next] | [standalone]
| From | Krishna Myneni <krishna.myneni@ccreweb.org> |
|---|---|
| Date | 2026-08-01 06:42 -0500 |
| Message-ID | <114km38$3ikhq$1@dont-email.me> |
| In reply to | #135291 |
On 8/1/26 03:23, Anton Ertl wrote: > Krishna Myneni <krishna.myneni@ccreweb.org> writes: >> glibc must have its own big number functions. > > That's certainly possible. > >> Conversion code in Forth for both directions should be possible to write >> using the FSL big number arithmetic package, big.4th. > > Early in the Gforth project I thought about implementing string-to-FP > and FP-to-string conversion myself, remembering the to papers about > theses topics in the PLDI 1990 proceedings. Then I looked at the > papers and found that these topics are very complicated, and need a > complicated implementation, and decided to spend my time on other > things. > The mathematical description as well as code such as dtoa.c can be difficult to understand. The output conversion at least does not seem terribly complicated. I am working out a Forth implementation of the output conversion for IEEE double-precision to ~60 decimal digits using the big.4th FSL code. The computation will not be efficient but it will be much easier to understand than dtoa.c and may also be useful to generate test cases for REPRESENT. At present my test code, fpio-test.4th, does not have any tests for double-precision binary floating point to decimal conversion. > In the meantime, other papers have been published on the topic, and > maybe some of the complications have been eliminated, but I have not > looked. For now standing on the shoulders of the libc developers is > good enough for me. A student of mine wrote an overview paper of four > FP-to-string algorithms > <http://www.complang.tuwien.ac.at/Bachelorarbeiten/orlov23.pdf>; it's > in German, but the last page references the original papers, which you > may find interesting. > Thanks. Efficient implementations of the conversions are apparently still a topic of recent research based on a quick search. -- KM
[toc] | [prev] | [next] | [standalone]
| From | Krishna Myneni <krishna.myneni@ccreweb.org> |
|---|---|
| Date | 2026-07-21 11:30 -0500 |
| Message-ID | <113o6r5$24mav$1@dont-email.me> |
| In reply to | #135244 |
On 7/21/26 04:40, albert@SPENARNC.XS4ALL.NL wrote:
> Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
>> I recently fixed a problem with kForth-Win32's conversion of decimal
>> strings to IEEE double precision floats e.g., with rounding mode set to
>> round nearest (with ties to eve), the string
>>
>> "1.000 000 000 000 000 111 022 302 462 515 654 042 363 166 809 082 031
>> 251 e0" (spaces added for clarity)
>>
>> converted to the IEEE 64-bit binary pattern (shown in hex, high-dword
>> low- dword)
>>
>> 3ff00000 00000000
>>
>> representing the exact number 1.000 ...
>>
>> instead of converting to the nearest representable IEEE 754 double
>> precision number,
>>
>> 3ff00000 00000001
>>
>> which has the value
>>
>> 1.000 000 000 000 000 222 044 604 925 031 308 084 726 333 618 164 062 500
>>
>
> The initial floating point number is 1/10 , the rounding mode
> doesn't matter much, because a host of larger numbers have been added.
>
> 1.000000000000000111022302462515654042363166809082031251E0 FS.
> 1.000000000000000110E0
>
You have a problem with your output conversion at the least, and maybe
also an input conversion problem. The output you show is not a
representable IEEE double precision number. See below. Have you run the
fpio-test.4th conversion tests with your Forth system?
Below is the output of a program, exact-double.c, listed further below.
Enter a real number, x:
1.000000000000000111022302462515654042363166809082031251E0
before: 1
x: 1.0000000000000002220446049250313080847263336181640625
after: 1.000000000000000444089209850062616169452667236328125
The input is not representable in exact form with IEEE double precision
floating point. The nearest representable value is the value for x,
printed below the input. The number "before" is the exactly
representable double precision number which is less than the input.
An improper conversion results in the converted binary floating point
number not having the value x. Your output canot be
"1.000000000000000110E0" for a valid conversion (or for any conversion)
if your output routine is working correctly.
The program below displays the nearest representable decimal value for
IEEE double precision for the given input. It also displays the exactly
representable values on either side of the nearest representable value.
Compile and link with recent version of gcc to obtain the same outputs
as shown above. Visual C++ will probably work as well. I don't do this
in Forth because we are currently missing FNEXTUP and FNEXTDOWN from
David Williams' IEEE FP proposal.
--
Krishna
=== exact-double.c ===
/*
Display representable double precision IEEE numbers
near a specified number.
*/
#include <stdio.h>
#include <math.h>
int main(void)
{
double x, before, after;
printf("\nEnter a real number, x: ");
scanf("%lf", &x);
before = nextafter(x, -INFINITY);
after = nextafter(x, INFINITY);
printf(" before: %.60g\n", before);
printf(" x: %.60g\n", x);
printf(" after: %.60g\n\n", after);
return 0;
}
=== end ===
[toc] | [prev] | [next] | [standalone]
| From | Krishna Myneni <krishna.myneni@ccreweb.org> |
|---|---|
| Date | 2026-07-21 14:47 -0500 |
| Message-ID | <113oid4$29nf1$1@dont-email.me> |
| In reply to | #135246 |
On 7/21/26 11:30, Krishna Myneni wrote: > On 7/21/26 04:40, albert@SPENARNC.XS4ALL.NL wrote: ... >> >> 1.000000000000000111022302462515654042363166809082031251E0 FS. >> 1.000000000000000110E0 >> > You have a problem with your output conversion at the least, and maybe > also an input conversion problem. The output you show is not a > representable IEEE double precision number. See below. Have you run the > fpio-test.4th conversion tests with your Forth system? > > Below is the output of a program, exact-double.c, listed further below. > > Enter a real number, x: > 1.000000000000000111022302462515654042363166809082031251E0 > before: 1 > x: 1.0000000000000002220446049250313080847263336181640625 > after: 1.000000000000000444089209850062616169452667236328125 > > ... Are you using IEEE 80-bit Extended Precision format? If so your output may be valid. This thread, and the tests mentioned here, only apply to IEEE 64-bit double precision floating point numbers. While input/output conversion for wider IEEE floating point formats are also important, we are not discussing that. In particular the tests in fpio-test.4th do not apply to the wider IEEE formats. -- KM
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.forth
csiph-web