Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #135242 > unrolled thread

kForth-Win32 fix for decimal string to double float conversion

Started byKrishna Myneni <krishna.myneni@ccreweb.org>
First post2026-07-20 09:48 -0500
Last post2026-08-24 18:55 -0500
Articles 20 on this page of 29 — 6 participants

Back to article view | Back to comp.lang.forth


Contents

  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 →


#135242 — kForth-Win32 fix for decimal string to double float conversion

FromKrishna Myneni <krishna.myneni@ccreweb.org>
Date2026-07-20 09:48 -0500
SubjectkForth-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]


#135244

Fromalbert@SPENARNC.XS4ALL.NL
Date2026-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]


#135245

FromKrishna Myneni <krishna.myneni@ccreweb.org>
Date2026-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]


#135263

Fromalbert@SPENARNC.XS4ALL.NL
Date2026-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]


#135264

Frompeter <peter.noreply@tin.it>
Date2026-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]


#135267

FromKrishna Myneni <krishna.myneni@ccreweb.org>
Date2026-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]


#135268

FromKrishna Myneni <krishna.myneni@ccreweb.org>
Date2026-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]


#135266

FromKrishna Myneni <krishna.myneni@ccreweb.org>
Date2026-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]


#135272

Fromdxf <dxforth@gmail.com>
Date2026-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]


#135275

FromKrishna Myneni <krishna.myneni@ccreweb.org>
Date2026-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]


#135284

Fromdxf <dxforth@gmail.com>
Date2026-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]


#135285

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2026-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]


#135286

Fromalbert@spenarnc.xs4all.nl
Date2026-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]


#135288

FromKrishna Myneni <krishna.myneni@ccreweb.org>
Date2026-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]


#135289

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2026-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]


#135290

FromKrishna Myneni <krishna.myneni@ccreweb.org>
Date2026-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]


#135291

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2026-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]


#135292

FromKrishna Myneni <krishna.myneni@ccreweb.org>
Date2026-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]


#135246

FromKrishna Myneni <krishna.myneni@ccreweb.org>
Date2026-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]


#135247

FromKrishna Myneni <krishna.myneni@ccreweb.org>
Date2026-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