• kForth-Win32 fix for decimal string to double float conversion

    From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Mon Jul 20 09:48:18 2026
    From Newsgroup: comp.lang.forth

    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






    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From albert@albert@SPENARNC.XS4ALL.NL to comp.lang.forth on Tue Jul 21 11:40:37 2026
    From Newsgroup: comp.lang.forth

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Tue Jul 21 06:20:54 2026
    From Newsgroup: comp.lang.forth

    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

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Tue Jul 21 11:30:29 2026
    From Newsgroup: comp.lang.forth

    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 ===


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Tue Jul 21 14:47:48 2026
    From Newsgroup: comp.lang.forth

    On 7/21/26 11:30, Krishna Myneni wrote:
    On 7/21/26 04:40, albert@SPENARNC.XS4ALL.NL wrote:
    ...

    -a 1.000000000000000111022302462515654042363166809082031251E0 FS.
    -a 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
    -a-a before: 1
    -a-a-a-a-a-a-a x: 1.0000000000000002220446049250313080847263336181640625
    -a-a-a 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

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From albert@albert@SPENARNC.XS4ALL.NL to comp.lang.forth on Sat Jul 25 16:08:35 2026
    From Newsgroup: comp.lang.forth

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From peter@peter.noreply@tin.it to comp.lang.forth on Sat Jul 25 17:07:16 2026
    From Newsgroup: comp.lang.forth

    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

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Sat Jul 25 13:17:04 2026
    From Newsgroup: comp.lang.forth

    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

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Sat Jul 25 13:22:05 2026
    From Newsgroup: comp.lang.forth

    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


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Sat Jul 25 13:30:28 2026
    From Newsgroup: comp.lang.forth

    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.-a 0.995717064571709700

    or to avoid the conversion to decimal

    10e100 fsin fh.-a 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

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From albert@albert@SPENARNC.XS4ALL.NL to comp.lang.forth on Sat Jul 25 23:42:45 2026
    From Newsgroup: comp.lang.forth

    Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
    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,

    [I think the Forth method would be to have hex floating point numbers
    that are exactly related to the internal representation instead of
    importing other languages problems. ]

    I have try at https://github.com/mynenik/kForth-Win32/tree/master/forth-src

    --
    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Sat Jul 25 18:47:35 2026
    From Newsgroup: comp.lang.forth

    On 7/25/26 16:42, albert@SPENARNC.XS4ALL.NL wrote:
    Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
    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,

    [I think the Forth method would be to have hex floating point numbers
    that are exactly related to the internal representation instead of
    importing other languages problems. ]

    Yes, if one wanted floating point numbers which are exactly represented
    in IEEE double precision, the best way is to enter the 64-bit binary
    values in hex form. However, this is not practical for most scientific computing.

    With regard to range reduction, consider that the number 5x10^9 is
    exactly represented in binary form for double precision. However,
    without accurate range reduction into the range -pi to +pi, there is significant error in computing the sine of this value using the x87 FSIN instruction.

    Range reduction of 5E9 using a double precision representation of 2PI
    with a scale factor of 795774715 to bring the angle argument into the
    range of -pi to +pi gives a huge loss of accuracy. Range reduction must
    be performed with a higher number of significant digits for 2PI than
    provided by double precision floating point arithmetic.



    I have try at https://github.com/mynenik/kForth-Win32/tree/master/forth-src


    See if the internal binary values (shown in hex as two dwords)
    correspond to the conversions for the decimal strings on your system.

    --
    KM


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Sun Jul 26 13:15:30 2026
    From Newsgroup: comp.lang.forth

    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! .

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From albert@albert@SPENARNC.XS4ALL.NL to comp.lang.forth on Sun Jul 26 13:11:21 2026
    From Newsgroup: comp.lang.forth
    --
    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From albert@albert@SPENARNC.XS4ALL.NL to comp.lang.forth on Sun Jul 26 13:22:52 2026
    From Newsgroup: comp.lang.forth

    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

    Trying a test of fpio-test.

    [ It use REGRESS instead of t{ . The main difference is that it kills,
    instead of reports. REGRESS is not for testing, but to safeguard. ]

    Note that I must convert a 8087 stack item to IEEE by storing
    and fetching it with F! and F@.

    WANT REGRESS -fp-
    REGRESS FINIT S:
    REGRESS -1.00000001335143196001808973960578441619873046875E-10 S:
    REGRESS HEX FDUP FS. S:
    REGRESS PAD F! PAD F@ FDUP FS. S:
    REGRESS PAD @ S: BDDB7CDFE0000000
    "
    hex_t{ r4 L@ -> aedbe6ff }t
    hex_t{ r8 2L@ -> bddb7cdf e0000000 }t
    " TYPE

    The outcome of the test:

    $-PREFIX : (WARNING) NOT PRESENT, THOUGH WANTED
    -fp- FINIT S: \ PASSED
    -fp- -1.00000001335143196001808973960578441619873046875E-10 S: \ PASSED -6.DF37F8000000000000_-9 -fp- HEX FDUP FS. S: \ PASSED -6.DF37F8000000000000_-9 -fp- PAD F! PAD F@ FDUP FS. S: \ PASSED -fp- PAD @ S: BDDB7CDFE0000000 \ PASSED

    My first impression is that trimming the number to IEEE generates the correct result.

    --
    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Sun Jul 26 07:18:04 2026
    From Newsgroup: comp.lang.forth

    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

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Sun Jul 26 07:23:11 2026
    From Newsgroup: comp.lang.forth

    On 7/26/26 06:22, 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

    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

    Trying a test of fpio-test.

    [ It use REGRESS instead of t{ . The main difference is that it kills, instead of reports. REGRESS is not for testing, but to safeguard. ]

    Note that I must convert a 8087 stack item to IEEE by storing
    and fetching it with F! and F@.

    WANT REGRESS -fp-
    REGRESS FINIT S:
    REGRESS -1.00000001335143196001808973960578441619873046875E-10 S:
    REGRESS HEX FDUP FS. S:
    REGRESS PAD F! PAD F@ FDUP FS. S:
    REGRESS PAD @ S: BDDB7CDFE0000000
    "
    hex_t{ r4 L@ -> aedbe6ff }t
    hex_t{ r8 2L@ -> bddb7cdf e0000000 }t
    " TYPE

    The outcome of the test:

    $-PREFIX : (WARNING) NOT PRESENT, THOUGH WANTED
    -fp- FINIT S: \ PASSED
    -fp- -1.00000001335143196001808973960578441619873046875E-10 S: \ PASSED -6.DF37F8000000000000_-9 -fp- HEX FDUP FS. S: \ PASSED -6.DF37F8000000000000_-9 -fp- PAD F! PAD F@ FDUP FS. S: \ PASSED
    -fp- PAD @ S: BDDB7CDFE0000000 \ PASSED


    That's encouraging. Try these two tests from the rounding section

    dec_t{ 1.000000000000000111022302462515654042363166809082031250e+00 !r
    }t
    hex_t{ r8 2L@ -> 3ff00000 00000000 }t

    dec_t{ 1.000000000000000111022302462515654042363166809082031251e+00 !r
    }t
    hex_t{ r8 2L@ -> 3ff00000 00000001 }t


    My first impression is that trimming the number to IEEE generates the correct result.

    Notice that the two decimal inputs are different by 1 in the last
    decimal place. But the round to nearest changes the converted bit
    pattern by 1 bit.

    --
    KM

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From albert@albert@SPENARNC.XS4ALL.NL to comp.lang.forth on Sun Jul 26 20:13:53 2026
    From Newsgroup: comp.lang.forth

    Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
    On 7/26/26 06:22, 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 >>>
    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

    Trying a test of fpio-test.

    [ It use REGRESS instead of t{ . The main difference is that it kills,
    instead of reports. REGRESS is not for testing, but to safeguard. ]

    Note that I must convert a 8087 stack item to IEEE by storing
    and fetching it with F! and F@.

    WANT REGRESS -fp-
    REGRESS FINIT S:
    REGRESS -1.00000001335143196001808973960578441619873046875E-10 S:
    REGRESS HEX FDUP FS. S:
    REGRESS PAD F! PAD F@ FDUP FS. S:
    REGRESS PAD @ S: BDDB7CDFE0000000
    "
    hex_t{ r4 L@ -> aedbe6ff }t
    hex_t{ r8 2L@ -> bddb7cdf e0000000 }t
    " TYPE

    The outcome of the test:

    $-PREFIX : (WARNING) NOT PRESENT, THOUGH WANTED
    -fp- FINIT S: \ PASSED
    -fp- -1.00000001335143196001808973960578441619873046875E-10 S: \ PASSED
    -6.DF37F8000000000000_-9 -fp- HEX FDUP FS. S: \ PASSED
    -6.DF37F8000000000000_-9 -fp- PAD F! PAD F@ FDUP FS. S: \ PASSED
    -fp- PAD @ S: BDDB7CDFE0000000 \ PASSED


    That's encouraging. Try these two tests from the rounding section

    dec_t{ 1.000000000000000111022302462515654042363166809082031250e+00 !r
    }t
    hex_t{ r8 2L@ -> 3ff00000 00000000 }t

    dec_t{ 1.000000000000000111022302462515654042363166809082031251e+00 !r
    }t
    hex_t{ r8 2L@ -> 3ff00000 00000001 }t

    Notice that the two decimal inputs are different by 1 in the last
    decimal place. But the round to nearest changes the converted bit
    pattern by 1 bit.

    Okay, now I got:
    S[ 3FF0000000000000 3FF0000000000001 ] 3FF0000000000001 ?
    ciforth ERROR # 41 : REGRESSION TEST FAILS, RETURN VALUE ERROR


    My first impression is that trimming the number to IEEE generates the correct
    result.

    This impression is wrong.
    Apparently I do not understand the fine points of this matter.


    My input method has the advantage of simplicity for
    lengthy input and doesn't stray too far from the wanted result.

    One step goes like
    ( digit parsed backward) FI+ BASE @ FI/

    FI+ and FI/ are the FIADD and FIDIV 8087 instructions.


    --
    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Mon Jul 27 12:20:18 2026
    From Newsgroup: comp.lang.forth

    On 7/26/26 13:13, albert@SPENARNC.XS4ALL.NL wrote:
    Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
    ...
    That's encouraging. Try these two tests from the rounding section

    dec_t{ 1.000000000000000111022302462515654042363166809082031250e+00 !r
    }t
    hex_t{ r8 2L@ -> 3ff00000 00000000 }t

    dec_t{ 1.000000000000000111022302462515654042363166809082031251e+00 !r
    }t
    hex_t{ r8 2L@ -> 3ff00000 00000001 }t

    Notice that the two decimal inputs are different by 1 in the last
    decimal place. But the round to nearest changes the converted bit
    pattern by 1 bit.

    Okay, now I got:
    S[ 3FF0000000000000 3FF0000000000001 ] 3FF0000000000001 ?
    ciforth ERROR # 41 : REGRESSION TEST FAILS, RETURN VALUE ERROR


    My first impression is that trimming the number to IEEE generates the correct
    result.

    This impression is wrong.
    Apparently I do not understand the fine points of this matter.

    The explanation of why the second test value has the lsb of the 52 bit fractional part of the converted number set is the following. We can
    ignore the implied 1 for the msb. That bit just adds the 1.0e0 to the
    number.

    Input 1)

    1.000000000000000111022302462515654042363166809082031250e+00

    the converted IEEE double precision number

    3ff0000000000000

    has the fractional part, all 52 of the least significant bits, set to
    zero. The exponent is also zero. This means that the nearest number
    rounding for the number is

    1.000 ... ... ...


    Input 2)

    1.000000000000000111022302462515654042363166809082031251e+00

    the converted IEEE double precision number is

    3ff0000000000001

    The lsb of the 52 bit fraction is now 1. The fractional part is now

    2^-52

    which, added to the implied msb of 1, is the next representable IEEE
    double precision floating point number:

    55 set-precision
    2.0e0 -52e0 F** 1.0e0 F+ FS. 1.000000000000000222044604925031308084726333618164062500e+00 ok

    The input for the second case is nearer to the representable number
    above, rather than it is to the representable number below this one,
    which is 1.000 ... ... ...

    In contrast, input 1) is closer to 1 than to the number above.

    --
    Krishna





    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Fri Jul 31 14:54:57 2026
    From Newsgroup: comp.lang.forth

    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.-a 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.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Fri Jul 31 08:35:34 2026
    From Newsgroup: comp.lang.forth

    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
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From albert@albert@spenarnc.xs4all.nl to comp.lang.forth on Fri Jul 31 12:05:14 2026
    From Newsgroup: comp.lang.forth

    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.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Fri Jul 31 07:54:05 2026
    From Newsgroup: comp.lang.forth

    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

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Fri Jul 31 16:55:52 2026
    From Newsgroup: comp.lang.forth

    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
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Fri Jul 31 14:40:33 2026
    From Newsgroup: comp.lang.forth

    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

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Sat Aug 1 08:23:19 2026
    From Newsgroup: comp.lang.forth

    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
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Sat Aug 1 06:42:30 2026
    From Newsgroup: comp.lang.forth

    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


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Tue Aug 11 07:24:06 2026
    From Newsgroup: comp.lang.forth

    On 7/20/26 09:48, Krishna Myneni wrote:
    ...

    "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

    ...
    I recently found a paper by Vern Paxson, a student of William Kahan, "A Program for Testing IEEE Decimal-Binary Conversion," 22 May 1991. This
    nicely written paper was apparently written for a CS class. It contains
    tables for "difficult" Decimal -> Binary conversions and for Binary ->
    Decimal conversions, with difficult meaning the required extra
    arithmetic precision over the starting precision (53 bits) in order to
    convert to the nearest double precision floating point which can be represented.


    For example, Table 1. indicates that converting the double-precision
    floating point number, 4891559871276714924261E+222 requires an
    arithmetic precision of 53 + 86 = 139 bits.

    The paper may be found at

    https://www.icir.org/vern/papers/testbase-report.pdf

    I am in the process of updating fpio-test.4th to include the conversion "stress tests" from Tables 1 through 4 of the paper. The Forth big
    number arithmetic code (FSL #47) may be used to check that the binary
    values of the significand and exponent (power of 2) are correct for
    decimal to binary conversions.

    --
    Krishna

    --- Synchronet 3.22a-Linux NewsLink 1.2