• ddfloat library: the behavior of >dd

    From marcel hendrix@mhx@iae.nl to comp.lang.forth on Thu Sep 10 19:33:31 2026
    From Newsgroup: comp.lang.forth

    ( I'm starting a new thread because "Getting the exponent of an x87
    float" is becoming unwieldy large )

    I ported D. Bailey's fp library functions to iForth in 2006. However,
    because there was no convenient way to test the accuracy of the
    double-double results, it has been unclear if the result were really
    accurate up to 106 bits, and if not, if there were bugs in my
    implementation.

    The most convenient way to test D. Bailey's package is to compare its
    output to MATLAB, because I can then use the vpa() function (a variable precision arithmetic package) through iForth's COM interface on Windows.

    As this will involve string manipulation I have to make sure the >DD
    function is robust. I encounter some problems that may or may not have
    been covered in the "Getting the exponent of an x87 float" thread.

    Here is the list so far:
    s" 9999999999999999999999999999999999999999999999999999d0" >dd
    ddfe. 1.00000000000000001224290705471e50 not ok
    s" 8999999999999999999999999999999999999999999999999999d0" >dd
    ddfe. 9.00000000000000066309858349023e49 not ok
    s" .9999999999999999999999999999999999999999999999999999d0" >dd
    ddfe. 1.000000000000000100000000000000e0 not ok
    s" 0.99999999999999999999d44" >dd ddfe. 1.00000000000000000000208925819e44 not ok
    s" 0.99999999999999999999d34" >dd
    ddfe. 1.00000000000000000001814749767e34 not ok
    s" 0.99999999999999999999d30" >dd
    ddfe. 9.99999999999999999972820130815e29 not ok
    s" 0.99999999999999999999d28" >dd ddfe. 0.99999999999999999999000000000e28 ok
    s" 0.9999999999999999999999999999999999999999999999999999d0" >dd ddfe. 1.000000000000000000000000000000e0 ok
    s" 1.9999999999999999999999999999999999999999999999999999d0" >dd
    ddfe. 2.000000000000000000000000000000e0 ok

    ... which hints that the exponent should not exceed +30 and that the
    number must start with "[optional sign][0<=digit<9]".

    s" 0.00000000000000000000001d" >dd ddfe. 1.000000000000000000005091539406e-23 not ok
    s" 0.000000000000000000001d" >dd ddfe. 0.999999999999999999988259524950e-21 not ok

    The mantissa should be smaller than 30 decimals?

    s" 0.0000000000000000001d" >dd ddfe. 0.999999999999999999995600113174e-19 not ok
    s" 0.00000000000000001d" >dd ddfe. 9.999999999999999999645978009888e-18 not ok
    s" 0.000000000000001d" >dd ddfe. 1.000000000000000000000000000000e-15 ok
    s" 0.0000000000000001d" >dd ddfe. 9.999999999999999999699073446189e-17 not ok
    s" 1.000000000000000d-16" >dd ddfe. 1.000000000000000000028598854846e-16 not ok
    s" 1.000000000000000d-15" >dd ddfe. 1.000000000000000000052694643620e-15 not ok
    s" 1.000000000000000d-5" >dd ddfe. 1.000000000000000000007126988157e-5 not ok
    s" 1.000000000000000d-1" >dd ddfe. 9.999999999999999999661186821098e-2 not ok

    ... which suggests that a negative exponent (or a number between 0 and
    1e-16) is a problem.

    s" 1e-30" >dd ddfe. 1.000000000000000000000000000000e-30 ok
    s" 1.0e-30" >dd ddfe. 0.999999999999999999986447472844e-30 not ok

    ... which tells me that there might be a problem when a decimal point is
    used, or that a buffer is overwritten.

    If I get reports that >dd ddfe. processes all of these fine on other
    Forths it may be advantageous to fix >dd ddfe. Otherwise, I'd better go straight for the MPFR libraries.

    -marcel
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Thu Sep 10 13:35:33 2026
    From Newsgroup: comp.lang.forth

    On 9/10/26 12:33 PM, marcel hendrix wrote:
    ( I'm starting a new thread because "Getting the exponent of an x87
    float" is becoming unwieldy large )

    I ported D. Bailey's fp library functions to iForth in 2006. However,
    because there was no convenient way to test the accuracy of the double- double results, it has been unclear if the result were really accurate
    up to 106 bits, and if not, if there were bugs in my implementation.

    The most convenient way to test D. Bailey's package is to compare its
    output to MATLAB, because I can then use the vpa() function (a variable precision arithmetic package) through iForth's COM interface on Windows.

    As this will involve string manipulation I have to make sure the >DD
    function is robust. I encounter some problems that may or may not have
    been covered in the "Getting the exponent of an x87 float" thread.

    Here is the list so far:
    -a s" 9999999999999999999999999999999999999999999999999999d0"-a-a >dd
    ddfe. 1.00000000000000001224290705471e50-a-a not ok
    -a s" 8999999999999999999999999999999999999999999999999999d0"-a-a >dd
    ddfe. 9.00000000000000066309858349023e49-a-a not ok
    -a s" .9999999999999999999999999999999999999999999999999999d0"-a >dd
    ddfe. 1.000000000000000100000000000000e0-a-a not ok
    -a s" 0.99999999999999999999d44"-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a >dd ddfe.
    1.00000000000000000000208925819e44-a-a not ok
    -a s" 0.99999999999999999999d34"-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a >dd
    ddfe. 1.00000000000000000001814749767e34-a-a not ok
    -a s" 0.99999999999999999999d30"-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a >dd
    ddfe. 9.99999999999999999972820130815e29-a-a not ok
    -a s" 0.99999999999999999999d28"-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a >dd ddfe.
    0.99999999999999999999000000000e28-a-a ok
    -a s" 0.9999999999999999999999999999999999999999999999999999d0" >dd ddfe. 1.000000000000000000000000000000e0-a-a ok
    -a s" 1.9999999999999999999999999999999999999999999999999999d0" >dd
    ddfe. 2.000000000000000000000000000000e0-a-a ok

    ... which hints that the exponent should not exceed +30 and that the
    number must start with "[optional sign][0<=digit<9]".

    The exponent range for double double numbers is the same as for ordinary double precision: 10^-308 to 10^+308. Because there are only about 31
    decimal digits of precision, it is possible to enter all numbers with at
    most 32 digits followed by a decimal exponent. In double precision,
    there are 16 decimal digits of precision and 17 decimal digits are
    enough to specify any number which can be represented.


    -a s" 0.00000000000000000000001d" >dd ddfe. 1.000000000000000000005091539406e-23-a not ok
    -a s" 0.000000000000000000001d"-a-a >dd ddfe. 0.999999999999999999988259524950e-21-a not ok

    The mantissa should be smaller than 30 decimals?


    -a s" 0.0000000000000000001d"-a-a-a-a >dd ddfe. 0.999999999999999999995600113174e-19-a not ok
    -a s" 0.00000000000000001d"-a-a-a-a-a-a >dd ddfe. 9.999999999999999999645978009888e-18-a not ok
    -a s" 0.000000000000001d"-a-a-a-a-a-a-a-a >dd ddfe. 1.000000000000000000000000000000e-15-a ok
    -a s" 0.0000000000000001d"-a-a-a-a-a-a-a >dd ddfe. 9.999999999999999999699073446189e-17-a not ok
    -a s" 1.000000000000000d-16"-a-a-a-a-a >dd ddfe. 1.000000000000000000028598854846e-16-a not ok
    -a s" 1.000000000000000d-15"-a-a-a-a-a >dd ddfe. 1.000000000000000000052694643620e-15-a not ok
    -a s" 1.000000000000000d-5"-a-a-a-a-a-a >dd ddfe. 1.000000000000000000007126988157e-5-a-a not ok
    -a s" 1.000000000000000d-1"-a-a-a-a-a-a >dd ddfe. 9.999999999999999999661186821098e-2-a-a not ok

    ... which suggests that a negative exponent (or a number between-a 0 and 1e-16) is a problem.

    -a s" 1e-30"-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a >dd ddfe. 1.000000000000000000000000000000e-30-a ok
    -a s" 1.0e-30"-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a >dd ddfe. 0.999999999999999999986447472844e-30-a not ok

    ... which tells me that there might be a problem when a decimal point is used, or that a buffer is overwritten.

    The term "mantissa" is a bit ambiguous, and people seem to use
    "significand" which in scientific notation consists of the single digit preceding the decimal point, followed by all significant digits trailing
    the decimal point.

    https://en.wikipedia.org/wiki/Significand


    If I get reports-a that >dd ddfe. processes all of these fine on other Forths it may be advantageous to fix >dd ddfe. Otherwise, I'd better go straight for the MPFR libraries.

    There's a huge speed advantage for double double precision arithmetic
    over multi-precision when 106 bit significand and the exponent range of ordinary double precision suffices. IMO, it's worth having a usable
    Forth library for double double arithmetic.

    --
    Krishna



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From marcel hendrix@mhx@iae.nl to comp.lang.forth on Thu Sep 10 22:10:30 2026
    From Newsgroup: comp.lang.forth

    On 9/10/2026 8:35 PM, Krishna Myneni wrote:

    If I get reports-a that >dd ddfe. processes all of these fine on other
    Forths it may be advantageous to fix >dd ddfe. Otherwise, I'd better
    go straight for the MPFR libraries.

    There's a huge speed advantage for double double precision arithmetic
    over multi-precision when 106 bit significand and the exponent range of ordinary double precision suffices. IMO, it's worth having a usable
    Forth library for double double arithmetic.

    I meant: use MPFR instead of vpa() to debug and check double-double.

    For circuit simulation, control, and system identification, it's
    possible to avoid >DD (although I'm curious what went wrong there).

    -marcel
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Thu Sep 10 16:51:44 2026
    From Newsgroup: comp.lang.forth

    On 9/10/26 15:10, marcel hendrix wrote:
    On 9/10/2026 8:35 PM, Krishna Myneni wrote:

    If I get reports-a that >dd ddfe. processes all of these fine on other
    Forths it may be advantageous to fix >dd ddfe. Otherwise, I'd better
    go straight for the MPFR libraries.

    There's a huge speed advantage for double double precision arithmetic
    over multi-precision when 106 bit significand and the exponent range
    of ordinary double precision suffices. IMO, it's worth having a usable
    Forth library for double double arithmetic.

    I meant: use MPFR instead of vpa() to debug and check double-double.

    For circuit simulation, control, and system identification, it's
    possible to avoid >DD (although I'm curious what went wrong there).


    Ah. I've used the double double code once or twice without using >DD at
    all, but it's certainly needed for general purpose use.

    --
    Krishna

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Fri Sep 11 12:16:46 2026
    From Newsgroup: comp.lang.forth

    On 11/09/2026 3:33 am, marcel hendrix wrote:
    ...
    If I get reports-a that >dd ddfe. processes all of these fine on other Forths it may be advantageous to fix >dd ddfe. Otherwise, I'd better go straight for the MPFR libraries.

    Thanks for the test.

    dd# 9999999999999999999999999999999999999999999999999999d0 ddfs. 1.0000000000000000000000000000000E52
    dd# 8999999999999999999999999999999999999999999999999999d0 ddfs. 9.0000000000000000000000000000000E51
    dd# .9999999999999999999999999999999999999999999999999999d0 ddfs. 1.0000000000000000000000000000000E0
    dd# 0.99999999999999999999d44 ddfs. 9.9999999999999999999000000000002E43
    dd# 0.99999999999999999999d34 ddfs. 9.9999999999999999999000000000000E33
    dd# 0.99999999999999999999d30 ddfs. 9.9999999999999999999000000000000E29
    dd# 0.99999999999999999999d28 ddfs. 9.9999999999999999999000000000000E27
    dd# 0.9999999999999999999999999999999999999999999999999999d0 ddfs. 1.0000000000000000000000000000000E0
    dd# 1.9999999999999999999999999999999999999999999999999999d0 ddfs. 2.0000000000000000000000000000000E0

    dd# 0.00000000000000000000001d ddfs. 1.0000000000000000000000000000000E-23
    dd# 0.000000000000000000001d ddfs. 1.0000000000000000000000000000000E-21

    dd# 0.0000000000000000001d ddfs. 1.0000000000000000000000000000000E-19
    dd# 0.00000000000000001d ddfs. 1.0000000000000000000000000000000E-17
    dd# 0.000000000000001d ddfs. 1.0000000000000000000000000000000E-15
    dd# 0.0000000000000001d ddfs. 1.0000000000000000000000000000000E-16
    dd# 1.000000000000000d-16 ddfs. 1.0000000000000000000000000000000E-16
    dd# 1.000000000000000d-15 ddfs. 1.0000000000000000000000000000000E-15
    dd# 1.000000000000000d-5 ddfs. 1.0000000000000000000000000000000E-5
    dd# 1.000000000000000d-1 ddfs. 1.0000000000000000000000000000000E-1

    dd# 1e-30 ddfs. 1.0000000000000000000000000000000E-30
    dd# 1.0e-30 ddfs. 1.0000000000000000000000000000000E-30


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From marcel hendrix@mhx@iae.nl to comp.lang.forth on Fri Sep 11 12:05:33 2026
    From Newsgroup: comp.lang.forth

    On 9/11/2026 4:16 AM, dxf wrote:
    [..]

    Near perfect.
    Quite a bit more useful than my results.

    -marcel

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From marcel hendrix@mhx@iae.nl to comp.lang.forth on Sat Sep 12 00:27:14 2026
    From Newsgroup: comp.lang.forth

    On 9/11/2026 12:05 PM, marcel hendrix wrote:
    On 9/11/2026 4:16 AM, dxf wrote:
    [..]

    Near perfect.
    Quite a bit more useful than my results.
    I have dropped JVN's parser and switched to yours.
    Indeed, a lot simpler and shorter, and bug free.
    None of the previously mentioned problems and no new anomalies.

    FORTH> TEST
    Addition: 1/3 + 1/6
    5.00000000000000e-001 -1.54074395550979e-033 <- should be this
    5.0000000000000000000e-0001 -1.5407439555097889288e-0033

    Subtraction: 1/3 - 1/6
    1.66666666666667e-001 9.25185853854297e-018 <- should be this
    1.6666666666666664964e-0001 9.2518585385429708806e-0018

    Multiplication: 6 * 1/6
    1.00000000000000e+000 0.00000000000000e+000 <- should be this
    1.0000000000000000000e+0000 0.0000000000000000000e+0000
    6 * 1/3
    2.00000000000000e+000 0.00000000000000e+000 <- should be this
    2.0000000000000000000e+0000 0.0000000000000000000e+0000

    Division: [1/3] / [1/6]
    2.00000000000000e+000 0.00000000000000e+000 <- should be this
    2.0000000000000000000e+0000 0.0000000000000000000e+0000

    [1/6] / [1/3]
    5.00000000000000e-001 0.00000000000000e+000 <- should be this
    5.0000000000000000000e-0001 0.0000000000000000000e+0000
    Square root: sqrt[1/324]
    5.55555555555556e-002 3.08395284618099e-018 <- should be this
    5.5555555555555553286e-0002 3.0839528461809899528e-0018 <-
    sqrt[1/324] = 1/18
    ... multiplied by 18
    1.00000000000000e+000 0.00000000000000e+000 <- should be this
    1.0000000000000000000e+0000 0.0000000000000000000e+0000

    FORTH> .TEST+
    -9 1.666666666666666666666666666666e-10
    -8 1.666666666666666666666666666666e-9
    -7 1.666666666666666666666666666666e-8
    -6 1.666666666666666666666666666666e-7
    -5 1.666666666666666666666666666666e-6
    -4 1.666666666666666666666666666666e-5
    -3 1.666666666666666666666666666666e-4
    -2 1.666666666666666666666666666666e-3
    -1 1.666666666666666666666666666666e-2
    0 1.666666666666666666666666666666e-1
    1 1.666666666666666666666666666666e0
    2 1.666666666666666666666666666666e1
    3 1.666666666666666666666666666666e2
    4 1.666666666666666666666666666666e3
    5 1.666666666666666666666666666666e4
    6 1.666666666666666666666666666666e5
    7 1.666666666666666666666666666666e6
    8 1.666666666666666666666666666666e7
    9 1.666666666666666666666666666666e8 3.141592653589793238462643383279e0
    -1.111122222333334444455555666659e-44 (
    -1.11112222233333444445555566666e-044 )
    1.111122222333334444455555666659e46 (
    1.11112222233333444445555566666e+046 )
    1.111122222333334444455555666659e1 ( 1.11112222233333444445555566666e+001 ) 1.111122222333000000000000000000e6 ( 1.11112222233300000000000000000e+006 )

    FORTH> PRINT-TEST
    1.000000000000000000000000000000e-34
    1.000000000000000000000000000000e-33
    1.000000000000000000000000000000e-32
    1.000000000000000000000000000000e-31
    1.000000000000000000000000000000e-30
    1.000000000000000000000000000000e-29
    1.000000000000000000000000000000e-28
    1.000000000000000000000000000000e-27
    1.000000000000000000000000000000e-26
    1.000000000000000000000000000000e-25
    1.000000000000000000000000000000e-24
    1.000000000000000000000000000000e-23
    1.000000000000000000000000000000e-22
    1.000000000000000000000000000000e-21
    1.000000000000000000000000000000e-20
    1.000000000000000000000000000000e-19
    1.000000000000000000000000000000e-18
    1.000000000000000000000000000000e-17
    1.000000000000000000000000000000e-16
    1.000000000000000000000000000000e-15
    1.000000000000000000000000000000e-14
    1.000000000000000000000000000000e-13
    1.000000000000000000000000000000e-12
    1.000000000000000000000000000000e-11
    1.000000000000000000000000000000e-10
    1.000000000000000000000000000000e-9
    1.000000000000000000000000000000e-8
    1.000000000000000000000000000000e-7
    1.000000000000000000000000000000e-6
    1.000000000000000000000000000000e-5
    1.000000000000000000000000000000e-4
    1.000000000000000000000000000000e-3
    1.000000000000000000000000000000e-2
    1.000000000000000000000000000000e-1
    1.000000000000000000000000000000e0
    1.000000000000000000000000000000e1
    1.000000000000000000000000000000e2
    1.000000000000000000000000000000e3
    1.000000000000000000000000000000e4
    1.000000000000000000000000000000e5
    1.000000000000000000000000000000e6
    1.000000000000000000000000000000e7
    1.000000000000000000000000000000e8
    1.000000000000000000000000000000e9
    1.000000000000000000000000000000e10
    1.000000000000000000000000000000e11
    1.000000000000000000000000000000e12
    1.000000000000000000000000000000e13
    1.000000000000000000000000000000e14
    1.000000000000000000000000000000e15
    1.000000000000000000000000000000e16
    1.000000000000000000000000000000e17
    1.000000000000000000000000000000e18
    1.000000000000000000000000000000e19
    1.000000000000000000000000000000e20
    1.000000000000000000000000000000e21
    1.000000000000000000000000000000e22
    1.000000000000000000000000000000e23
    1.000000000000000000000000000000e24
    1.000000000000000000000000000000e25
    1.000000000000000000000000000000e26
    1.000000000000000000000000000000e27
    1.000000000000000000000000000000e28
    1.000000000000000000000000000000e29
    1.000000000000000000000000000000e30
    1.000000000000000000000000000000e31
    1.000000000000000000000000000000e32
    1.000000000000000000000000000000e33

    FORTH> TESTS
    ddexp max delta = 9.9471290646179302422e-0015
    ddln max delta = 1.1100635206879409926e-0016
    ddlog max delta = 1.1092437240280354566e-0016
    ddsin max delta = 5.5584892248111063040e-0017
    ddcos max delta = 5.5583702957907087366e-0017
    ddtan max delta = 3.1168367029577738248e-0014
    ddasin max delta = 1.8513496126496535048e-0016
    ddacos max delta = 3.5092045508040913926e-0016
    ddatan max delta = 1.1107850143462055686e-0016
    ddsinh max delta = 5.2214958028216371202e-0016
    ddcosh max delta = 5.0802472104219330562e-0016
    ddtanh max delta = 3.4287817519898081282e-0016
    ddasinh max delta = 1.0464329155476988164e-0012
    ddacosh max delta = 7.2614989467132989444e-0013
    ddatanh max delta = 6.2797216632193505288e-0013

    FORTH> exactmulbench
    0.131 seconds elapsed.

    FORTH> 1e-30 PTEST
    Found 0 errors. ok


    I can now test D.Bailey's library. The functions are indeed
    accurate to about 30 decimals.

    FORTH> CR S" ddexp" S" exp" 1e-16 TESTFUNC

    ddexp( 1.000000000000000000000000000000e-30 ) has error -1.348833849820495919788345147690e-40
    ddexp( 1.000000000000000000000000000000e-2 ) has error 8.600338075353514991189339041209e-31
    ddexp( 2.000000000000000000000000000000e-2 ) has error 1.514353036216258607670262638799e-31
    ddexp( 2.999999999999999826527652402320e-2 ) has error 2.998974504981413075682514105269e-31
    ddexp( 4.000000000000000000000000000000e-2 ) has error -1.452559168452108803416741833219e-31
    ddexp( 5.000000000000000173472347597680e-2 ) has error 1.003157524415731921450355576670e-30
    ddexp( 6.000000000000000346944695195361e-2 ) has error 1.178084960660913285467247510960e-31
    ddexp( 7.000000000000000520417042793042e-2 ) has error 2.746851445242115045880974909720e-30
    ddexp( 8.000000000000000000000000000000e-2 ) has error 1.888500198575557846784067350310e-30
    ddexp( 8.999999999999999479582957206958e-2 ) has error 1.280659362172425127316005064650e-30 ok

    FORTH> CR S" ddln" S" log" 1e-16 TESTFUNC

    ddln( 1.000000000000000000000000000000e-30 ) has error -1.092622802649907621080041761850e-29
    ddln( 1.000000000000000000000000000000e-2 ) has error -7.284152019694084680689251000960e-31
    ddln( 2.000000000000000000000000000000e-2 ) has error -5.518471264794716993160814762439e-31
    ddln( 2.999999999999999826527652402320e-2 ) has error -5.377157022109784478978614015070e-31
    ddln( 4.000000000000000000000000000000e-2 ) has error -1.375279050986547445573717949980e-30
    ddln( 5.000000000000000173472347597680e-2 ) has error 4.586224700703673904266268872329e-31
    ddln( 6.000000000000000346944695195361e-2 ) has error -5.278142930437839408059431590239e-31
    ddln( 7.000000000000000520417042793042e-2 ) has error -1.228777480697171374987884452209e-31
    ddln( 8.000000000000000000000000000000e-2 ) has error -1.198710975502350395330748776849e-30
    ddln( 8.999999999999999479582957206958e-2 ) has error 7.657667231090196888092519365119e-31 ok

    FORTH> CR S" ddlog" S" log10" 1e-16 TESTFUNC

    ddlog( 1.000000000000000000000000000000e-30 ) has error 0e
    ddlog( 1.000000000000000000000000000000e-2 ) has error 0e
    ddlog( 2.000000000000000000000000000000e-2 ) has error -5.069732316644259374107623408930e-31
    ddlog( 2.999999999999999826527652402320e-2 ) has error -6.345563982593910129511184933990e-31
    ddlog( 4.000000000000000000000000000000e-2 ) has error -1.013946463696193859453489528030e-30
    ddlog( 5.000000000000000173472347597680e-2 ) has error -4.438044265683155715389947391819e-31
    ddlog( 6.000000000000000346944695195361e-2 ) has error -5.708681387428622982654112706199e-31
    ddlog( 7.000000000000000520417042793042e-2 ) has error -5.634574788991325446928567969579e-31
    ddlog( 8.000000000000000000000000000000e-2 ) has error -5.209196953607374225988345459659e-31
    ddlog( 8.999999999999999479582957206958e-2 ) has error 3.842429167450690235182823430440e-31 ok

    \ CR S" ddatan2" S" atan2" 1e-16 TESTFUNC
    \ two arguments ...

    FORTH> CR S" ddsin" S" sin" 1e-16 TESTFUNC

    ddsin( 1.000000000000000000000000000000e-30 ) has error 1.290964874928831515047833236409e-70
    ddsin( 1.000000000000000000000000000000e-2 ) has error 7.290389631748150273206057203279e-34
    ddsin( 2.000000000000000000000000000000e-2 ) has error 4.515171680020113802233606431339e-33
    ddsin( 2.999999999999999826527652402320e-2 ) has error 1.024305279605862250462179155179e-32
    ddsin( 4.000000000000000000000000000000e-2 ) has error 4.539256677392102516663408232700e-33
    ddsin( 5.000000000000000173472347597680e-2 ) has error 3.134065411729161552364095933970e-34
    ddsin( 6.000000000000000346944695195361e-2 ) has error 4.950193885214817859084190885630e-33
    ddsin( 7.000000000000000520417042793042e-2 ) has error 5.968689191909616265825855195940e-33
    ddsin( 8.000000000000000000000000000000e-2 ) has error 7.197947100174773392659851343960e-33
    ddsin( 8.999999999999999479582957206958e-2 ) has error 5.239029175657238047432152538220e-33 ok

    FORTH> CR S" ddsin" S" cos" 1e-16 TESTFUNC

    ddsin( 1.000000000000000000000000000000e-30 ) has error 1.000000000000000000000000000000e0
    ddsin( 1.000000000000000000000000000000e-2 ) has error 9.899501670824986130977154954829e-1
    ddsin( 2.000000000000000000000000000000e-2 ) has error 9.798013399732446990462052961449e-1
    ddsin( 2.999999999999999826527652402320e-2 ) has error 9.695545335464918572896091718730e-1
    ddsin( 4.000000000000000000000000000000e-2 ) has error 9.592107724743437808620239464129e-1
    ddsin( 5.000000000000000173472347597680e-2 ) has error 9.487710911242879159487502487220e-1
    ddsin( 6.000000000000000346944695195361e-2 ) has error 9.382365334557595626773247891020e-1
    ddsin( 7.000000000000000520417042793042e-2 ) has error 9.276081529157468050889411695019e-1
    ddsin( 8.000000000000000000000000000000e-2 ) has error 9.168870123334466976708304273190e-1
    ddsin( 8.999999999999999479582957206958e-2 ) has error 9.060741838139832090524364378170e-1 ok

    FORTH> CR S" ddcos" S" cos" 1e-16 TESTFUNC

    ddcos( 1.000000000000000000000000000000e-30 ) has error 0e
    ddcos( 1.000000000000000000000000000000e-2 ) has error 6.673212561067486843840793607170e-33
    ddcos( 2.000000000000000000000000000000e-2 ) has error 7.526312612417050062625416940190e-32
    ddcos( 2.999999999999999826527652402320e-2 ) has error 4.991119505465397429820441385450e-32
    ddcos( 4.000000000000000000000000000000e-2 ) has error 3.466045735058796483333400738680e-32
    ddcos( 5.000000000000000173472347597680e-2 ) has error 5.711477847116620720646795216269e-32
    ddcos( 6.000000000000000346944695195361e-2 ) has error 3.490930828317319771611444452900e-33
    ddcos( 7.000000000000000520417042793042e-2 ) has error 9.840437648319452183938735868770e-32
    ddcos( 8.000000000000000000000000000000e-2 ) has error 1.138463638195948363383308790010e-32
    ddcos( 8.999999999999999479582957206958e-2 ) has error 2.273955199333038303450258665160e-32 ok

    FORTH> CR S" ddtan" S" tan" 1e-16 TESTFUNC

    ddtan( 1.000000000000000000000000000000e-30 ) has error 1.290964874928831515047833236409e-70
    ddtan( 1.000000000000000000000000000000e-2 ) has error 1.356498499969104507969362088660e-34
    ddtan( 2.000000000000000000000000000000e-2 ) has error 7.499427041092531945789983216280e-33
    ddtan( 2.999999999999999826527652402320e-2 ) has error 7.915306915937973624752303890500e-33
    ddtan( 4.000000000000000000000000000000e-2 ) has error 2.284921091621521695851025139100e-33
    ddtan( 5.000000000000000173472347597680e-2 ) has error -3.805459407084820375805004111260e-33
    ddtan( 6.000000000000000346944695195361e-2 ) has error 3.361910016461688140288158486589e-34
    ddtan( 7.000000000000000520417042793042e-2 ) has error 4.554769145413700003976460109889e-34
    ddtan( 8.000000000000000000000000000000e-2 ) has error 3.083540312232744705631474629049e-33
    ddtan( 8.999999999999999479582957206958e-2 ) has error 9.024430237840674891541669272820e-33 ok

    FORTH> CR S" ddasin" S" asin" 1e-16 TESTFUNC

    ddasin( 1.000000000000000000000000000000e-30 ) has error 1.290964874928831515047833236409e-70
    ddasin( 1.000000000000000000000000000000e-2 ) has error 3.836785690854971254728706845369e-34
    ddasin( 2.000000000000000000000000000000e-2 ) has error 7.214987008818724808571807850710e-33
    ddasin( 2.999999999999999826527652402320e-2 ) has error 1.530078737960660717704968378030e-32
    ddasin( 4.000000000000000000000000000000e-2 ) has error 7.121489294333722604341271065450e-33
    ddasin( 5.000000000000000173472347597680e-2 ) has error 2.039607022291208069536436098360e-33
    ddasin( 6.000000000000000346944695195361e-2 ) has error -1.959980667389534150441733218940e-34
    ddasin( 7.000000000000000520417042793042e-2 ) has error 3.469938050168774031426656916730e-33
    ddasin( 8.000000000000000000000000000000e-2 ) has error 7.888042573442366724857125092560e-33
    ddasin( 8.999999999999999479582957206958e-2 ) has error 9.208231726154620277253703885049e-33 ok

    FORTH> CR S" ddacos" S" acos" 1e-16 TESTFUNC

    ddacos( 1.000000000000000000000000000000e-30 ) has error 7.514420985121228877154091890689e-31
    ddacos( 1.000000000000000000000000000000e-2 ) has error 7.610584200509264430482897053479e-31
    ddacos( 2.000000000000000000000000000000e-2 ) has error 9.742271114832300210533753864949e-31
    ddacos( 2.999999999999999826527652402320e-2 ) has error 6.161413112043154407336782795309e-31
    ddacos( 4.000000000000000000000000000000e-2 ) has error 8.543206092456192420392579168299e-31
    ddacos( 5.000000000000000173472347597680e-2 ) has error 4.694024916190571586141666934200e-31
    ddacos( 6.000000000000000346944695195361e-2 ) has error 5.016380966857150320965084866029e-31
    ddacos( 7.000000000000000520417042793042e-2 ) has error 8.279721607179567762790112815190e-31
    ddacos( 8.000000000000000000000000000000e-2 ) has error 1.235540558272262341440469067930e-31
    ddacos( 8.999999999999999479582957206958e-2 ) has error 5.622338669957151670971241249210e-31 ok

    FORTH> CR S" ddatan" S" atan" 1e-16 TESTFUNC

    ddatan( 1.000000000000000000000000000000e-30 ) has error 1.290964874928831515047833236409e-70
    ddatan( 1.000000000000000000000000000000e-2 ) has error 5.485613684696977471531700996090e-34
    ddatan( 2.000000000000000000000000000000e-2 ) has error 6.487949232904254807669862100440e-33
    ddatan( 2.999999999999999826527652402320e-2 ) has error 1.195752602792821075907015140519e-32
    ddatan( 4.000000000000000000000000000000e-2 ) has error 5.403597016275488426646022725890e-33
    ddatan( 5.000000000000000173472347597680e-2 ) has error -2.924144718370069112308118474640e-33
    ddatan( 6.000000000000000346944695195361e-2 ) has error 2.285558054607446306956452052530e-33
    ddatan( 7.000000000000000520417042793042e-2 ) has error 3.856519790969437242620035860489e-33
    ddatan( 8.000000000000000000000000000000e-2 ) has error 2.356915763086840590404552361310e-33
    ddatan( 8.999999999999999479582957206958e-2 ) has error 6.163294222026993156343182759780e-33 ok

    FORTH> CR S" ddsinh" S" sinh" 1e-16 TESTFUNC

    ddsinh( 1.000000000000000000000000000000e-30 ) has error 1.290964874928831515047833236409e-70
    ddsinh( 1.000000000000000000000000000000e-2 ) has error 1.738017642488525580906385444570e-33
    ddsinh( 2.000000000000000000000000000000e-2 ) has error 1.284501895737655321054043087620e-33
    ddsinh( 2.999999999999999826527652402320e-2 ) has error 8.589789601391734571244827357840e-33
    ddsinh( 4.000000000000000000000000000000e-2 ) has error 4.429027506164139776058216919020e-33
    ddsinh( 5.000000000000000173472347597680e-2 ) has error 3.215602707290917444503530202479e-34
    ddsinh( 6.000000000000000346944695195361e-2 ) has error -2.535197330307830264290663865449e-31
    ddsinh( 7.000000000000000520417042793042e-2 ) has error 1.788268195823099216597933888669e-30
    ddsinh( 8.000000000000000000000000000000e-2 ) has error 9.398450775735506187267743397249e-31
    ddsinh( 8.999999999999999479582957206958e-2 ) has error 6.182399680310202146071100103750e-31 ok

    FORTH> CR S" ddcosh" S" cosh" 1e-16 TESTFUNC

    ddcosh( 1.000000000000000000000000000000e-30 ) has error 0e
    ddcosh( 1.000000000000000000000000000000e-2 ) has error 4.482957896931047604239708815079e-31
    ddcosh( 2.000000000000000000000000000000e-2 ) has error 2.301508014317915376917934815289e-31
    ddcosh( 2.999999999999999826527652402320e-2 ) has error 9.613076609377395707317593443200e-31
    ddcosh( 4.000000000000000000000000000000e-2 ) has error 5.031505556728802848628203921139e-32
    ddcosh( 5.000000000000000173472347597680e-2 ) has error 6.828359640406699666560249690980e-31
    ddcosh( 6.000000000000000346944695195361e-2 ) has error 1.913282292213774664529525053199e-31
    ddcosh( 7.000000000000000520417042793042e-2 ) has error 5.485832495795734903008245973260e-31
    ddcosh( 8.000000000000000000000000000000e-2 ) has error 6.386551210018948180861637718999e-31
    ddcosh( 8.999999999999999479582957206958e-2 ) has error 8.624193943245994802142911611059e-31 ok

    FORTH> CR S" ddtanh" S" tanh" 1e-16 TESTFUNC

    ddtanh( 1.000000000000000000000000000000e-30 ) has error -8.333642060758499999999987089119e-47
    ddtanh( 1.000000000000000000000000000000e-2 ) has error 7.844975100106199584188090790880e-31
    ddtanh( 2.000000000000000000000000000000e-2 ) has error -4.734972483045822567043754674039e-31
    ddtanh( 2.999999999999999826527652402320e-2 ) has error 2.865778710387485567904833251770e-31
    ddtanh( 4.000000000000000000000000000000e-2 ) has error -2.002502897236812132009267986099e-31
    ddtanh( 5.000000000000000173472347597680e-2 ) has error 2.692826102390931598049100319459e-31
    ddtanh( 6.000000000000000346944695195361e-2 ) has error -2.580485979064130394226843064729e-31
    ddtanh( 7.000000000000000520417042793042e-2 ) has error 1.772131697238414674415147230000e-30
    ddtanh( 8.000000000000000000000000000000e-2 ) has error 9.292226091414370403296759748630e-31
    ddtanh( 8.999999999999999479582957206958e-2 ) has error 6.110342827488042702178137829269e-31 ok

    FORTH> CR S" ddasinh" S" asinh" 1e-16 TESTFUNC

    ddasinh( 1.000000000000000000000000000000e-30 ) has error -8.333642060758499999999987089119e-47
    ddasinh( 1.000000000000000000000000000000e-2 ) has error -1.204017783513088875087169292859e-33
    ddasinh( 2.000000000000000000000000000000e-2 ) has error -1.020338821497062001860839183569e-32
    ddasinh( 2.999999999999999826527652402320e-2 ) has error 4.269470267912267380624194688089e-31
    ddasinh( 4.000000000000000000000000000000e-2 ) has error 1.973706240112667547747601759499e-31
    ddasinh( 5.000000000000000173472347597680e-2 ) has error 1.203857231291711272345953843090e-31
    ddasinh( 6.000000000000000346944695195361e-2 ) has error -3.126948516141051007893085333899e-31
    ddasinh( 7.000000000000000520417042793042e-2 ) has error -1.770134963051862291627229247179e-31
    ddasinh( 8.000000000000000000000000000000e-2 ) has error 2.057312346823413199351525064629e-31
    ddasinh( 8.999999999999999479582957206958e-2 ) has error 5.016247807688765416006818398420e-31 ok

    \ FORTH> CR S" ddacosh" S" acosh" 1e-16 TESTFUNC
    \ is complex...

    FORTH> CR S" ddatanh" S" atanh" 1e-16 TESTFUNC

    ddatanh( 1.000000000000000000000000000000e-30 ) has error -8.333642060758499999999987089119e-47
    ddatanh( 1.000000000000000000000000000000e-2 ) has error -4.577611290134768056843627501779e-32
    ddatanh( 2.000000000000000000000000000000e-2 ) has error 6.390480763559417940367094184680e-33
    ddatanh( 2.999999999999999826527652402320e-2 ) has error 3.230097283984874648927682648819e-32
    ddatanh( 4.000000000000000000000000000000e-2 ) has error -4.011799660821192898181963685989e-32
    ddatanh( 5.000000000000000173472347597680e-2 ) has error 5.958276002720974224428216113209e-32
    ddatanh( 6.000000000000000346944695195361e-2 ) has error 1.086191751963114892868664141139e-31
    ddatanh( 7.000000000000000520417042793042e-2 ) has error 3.095731704082193474233882143270e-32
    ddatanh( 8.000000000000000000000000000000e-2 ) has error 1.104977500424901871362041159020e-31
    ddatanh( 8.999999999999999479582957206958e-2 ) has error -1.049074159649000666264780467730e-31 ok

    -marcel
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Fri Sep 11 20:29:31 2026
    From Newsgroup: comp.lang.forth

    On 9/11/26 5:27 PM, marcel hendrix wrote:
    On 9/11/2026 12:05 PM, marcel hendrix wrote:
    On 9/11/2026 4:16 AM, dxf wrote:
    [..]

    Near perfect.
    Quite a bit more useful than my results.
    I have dropped JVN's parser and switched to yours.
    Indeed, a lot simpler and shorter, and bug free.
    None of the previously mentioned problems and no new anomalies.
    ...

    Good news. I lost track of the sequence of patches dxforth made. Is
    there an update of the entire ddfloat library on pastebin?

    --
    Krishna



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Sat Sep 12 12:02:39 2026
    From Newsgroup: comp.lang.forth

    On 12/09/2026 11:29 am, Krishna Myneni wrote:
    On 9/11/26 5:27 PM, marcel hendrix wrote:
    On 9/11/2026 12:05 PM, marcel hendrix wrote:
    On 9/11/2026 4:16 AM, dxf wrote:
    [..]

    Near perfect.
    Quite a bit more useful than my results.
    I have dropped JVN's parser and switched to yours.
    Indeed, a lot simpler and shorter, and bug free.
    None of the previously mentioned problems and no new anomalies.
    ...

    Good news. I lost track of the sequence of patches dxforth made. Is there an update of the entire ddfloat library on pastebin?

    https://pastebin.com/TdcLJhXP


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From marcel hendrix@mhx@iae.nl to comp.lang.forth on Sat Sep 12 10:45:54 2026
    From Newsgroup: comp.lang.forth

    On 9/12/2026 3:29 AM, Krishna Myneni wrote:
    On 9/11/26 5:27 PM, marcel hendrix wrote:
    On 9/11/2026 12:05 PM, marcel hendrix wrote:
    On 9/11/2026 4:16 AM, dxf wrote:
    [..]

    Near perfect.
    Quite a bit more useful than my results.
    I have dropped JVN's parser and switched to yours.
    Indeed, a lot simpler and shorter, and bug free.
    None of the previously mentioned problems and no new anomalies.
    ...

    Good news. I lost track of the sequence of patches dxforth made. Is
    there an update of the entire ddfloat library on pastebin?

    I *only* used the >DD definition found in http://dxforth.webhop.org/finput.html . It has a rough spot: it does not
    catch invalid floats like JVN's did. S" -NAN +NAN" >DD gave an infinite
    loop in my tests. Maybe a "safe" >DDS could be added.-marcel
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Sat Sep 12 19:51:46 2026
    From Newsgroup: comp.lang.forth

    On 12/09/2026 6:45 pm, marcel hendrix wrote:
    On 9/12/2026 3:29 AM, Krishna Myneni wrote:
    On 9/11/26 5:27 PM, marcel hendrix wrote:
    On 9/11/2026 12:05 PM, marcel hendrix wrote:
    On 9/11/2026 4:16 AM, dxf wrote:
    [..]

    Near perfect.
    Quite a bit more useful than my results.
    I have dropped JVN's parser and switched to yours.
    Indeed, a lot simpler and shorter, and bug free.
    None of the previously mentioned problems and no new anomalies.
    ...

    Good news. I lost track of the sequence of patches dxforth made. Is there an update of the entire ddfloat library on pastebin?

    I *only* used the >DD definition found in http://dxforth.webhop.org/finput.html . It has a rough spot: it does not catch invalid floats like JVN's did. S" -NAN +NAN" >DD gave an infinite loop in my tests. Maybe a "safe" >DDS could be added.-marcel

    Printing an invalid float (junk input) will hang too and is perhaps the
    greater issue. Do we have a rigorous definition for what is 'invalid'
    when it comes to these synthesized doubles? Because if not, there can't
    be a solution.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Sat Sep 12 22:47:32 2026
    From Newsgroup: comp.lang.forth

    On 12/09/2026 6:45 pm, marcel hendrix wrote:
    ...
    I *only* used the >DD definition found in http://dxforth.webhop.org/finput.html . It has a rough spot: it does not catch invalid floats like JVN's did. S" -NAN +NAN" >DD gave an infinite loop in my tests. Maybe a "safe" >DDS could be added.-marcel

    Testing my DDFLOAT.F on Win32Forth:

    S" +NAN -NAN" >DD . 0 ok \ flag=false

    DD# +NAN -NAN
    ^^^^
    Error(-2): +NAN bad float

    OTOH the following *will* get through:

    DD# 1e400 ok

    f.s {2} +NAN +NAN ok

    The original >DD accepts 1e400 gives the same NAN-NAN result.

    The latter result when presented to DDFS. will cause an infinite loop due to the NORMALIZE word. This problem existed in the original DDFS. How one
    fixes it depends on what is available. If your forth includes a word that tests TOS for a NAN/INF etc. then you're in luck. Let's call that word:

    NAN? ( r -- flag )

    Fixing DDFS. (or what have you) is simply a matter of testing for NAN/INF before passing to NORMALIZE (which BTW can't handle 0.0E either). In your
    case the fix would be something like this:

    FOVER F0= IF F2DROP S" 0e" EXIT ENDIF
    F2DUP NAN? >R NAN? R> OR IF F2DROP S" NAN/INF" EXIT ENDIF

    HTH

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Sat Sep 12 10:24:56 2026
    From Newsgroup: comp.lang.forth

    On 9/11/26 9:02 PM, dxf wrote:
    On 12/09/2026 11:29 am, Krishna Myneni wrote:
    On 9/11/26 5:27 PM, marcel hendrix wrote:
    On 9/11/2026 12:05 PM, marcel hendrix wrote:
    On 9/11/2026 4:16 AM, dxf wrote:
    [..]

    Near perfect.
    Quite a bit more useful than my results.
    I have dropped JVN's parser and switched to yours.
    Indeed, a lot simpler and shorter, and bug free.
    None of the previously mentioned problems and no new anomalies.
    ...

    Good news. I lost track of the sequence of patches dxforth made. Is there an update of the entire ddfloat library on pastebin?

    https://pastebin.com/TdcLJhXP


    Got it. Thank you.

    --
    KM

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Sun Sep 13 03:14:24 2026
    From Newsgroup: comp.lang.forth

    In addition to NAN/INFs causing DDFS. to enter an infinite loop, numbers that are too small/large can also do so. Below is a patch that attempts to fix these issues. The patch can be applied to the DDFLOAT version here:

    https://pastebin.com/TdcLJhXP

    Implementation of the NAN? function I leave to users as there several options - none of which are easy, portable, and foolproof. But I'm always willing to be surprised.

    ---8<---

    \ Patch for DDFLOAT.F 2026-09-13
    \
    \ Fix infinite loop displaying floats that are:
    \ - too small/large
    \ - NAN/INF **
    \
    \ ** requires a function that can detect NAN/INF e.g.
    \ NAN? ( F: r -- ) ( -- flag )
    \

    : fzero ( x xx -- ) DDDROP S" 0.E0" HOLDS 0 ;

    : range? ( r -- r 0 | -1 ) \ handle problem numbers
    FOVER F0= IF fzero EXIT THEN
    \ FDUP NAN? >R FOVER NAN? R> OR IF
    \ DDDROP S" NAN/INF" HOLDS 0 EXIT
    \ THEN
    getpower dup -298 < IF drop fzero EXIT THEN
    299 > IF DDDROP S" INF" HOLDS 0 EXIT THEN
    -1
    ;

    : (DDFS.) ( dd -- c-addr u ) \ string double-double in E-format
    <# range? IF
    getsign >R
    getpower ( x xx n)
    normalize >R ( y yy)
    peeldigits copydigits
    dig$ maxdig ( a u) 0digit-fix R> + \ adjust exp
    ( p) DUP ABS 0 #S 2DROP SIGN \ exponent
    [char] E HOLD ( a u)
    1- OVER 1+ SWAP HOLDS [char] . HOLD C@ HOLD
    R> ( s) IF [char] - HOLD THEN
    THEN 0 0 #>
    ;

    \\

    cr
    ok
    dd# 1e-296 ddfs. 1.0000000000000000000000000000000E-296 ok
    dd# 1e-297 ddfs. 1.0000000000000000000000000000000E-297 ok
    dd# 1e-298 ddfs. 1.0000000000000000000000000000000E-298 ok
    dd# 1e-299 ddfs. 0.E0 ok
    dd# 1e-300 ddfs. 0.E0 ok
    dd# 1e-301 ddfs. 0.E0 ok
    dd# 1e-302 ddfs. 0.E0 ok
    dd# 1e-303 ddfs. 0.E0 ok
    cr
    ok
    dd# 1e+296 ddfs. 1.0000000000000000000000000000001E296 ok
    dd# 1e+297 ddfs. 1.0000000000000000000000000000001E297 ok
    dd# 1e+298 ddfs. 1.0000000000000000000000000000001E298 ok
    dd# 1e+299 ddfs. 1.0000000000000000000000000000001E299 ok
    dd# 1e+300 ddfs. INF ok
    dd# 1e+301 ddfs. INF ok
    \ dd# 1e+302 ddfs. NAN/INF ok
    \ dd# 1e+303 ddfs. NAN/INF ok
    \ dd# 1e+304 ddfs. NAN/INF ok
    \ dd# 1e+305 ddfs. NAN/INF ok

    ---8<---


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Sat Sep 12 13:02:29 2026
    From Newsgroup: comp.lang.forth

    On 9/12/26 12:14 PM, dxf wrote:
    In addition to NAN/INFs causing DDFS. to enter an infinite loop, numbers that are too small/large can also do so. Below is a patch that attempts to fix these issues. The patch can be applied to the DDFLOAT version here:

    https://pastebin.com/TdcLJhXP

    Implementation of the NAN? function I leave to users as there several options -
    none of which are easy, portable, and foolproof. But I'm always willing to be
    surprised.

    ...


    See https://github.com/mynenik/kForth-32/blob/master/forth-src/ieee-754.4th

    The IEEE proposal, in progress, calls this word FNAN?

    The file linked above provides standard definitions for FNAN? as well as
    tests for plus and minus infinities and normal and subnormal numbers.
    There are tests for these words as well.

    --
    KM

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

    On 13/09/2026 4:02 am, Krishna Myneni wrote:
    On 9/12/26 12:14 PM, dxf wrote:
    In addition to NAN/INFs causing DDFS. to enter an infinite loop, numbers that
    are too small/large can also do so.-a Below is a patch that attempts to fix >> these issues.-a The patch can be applied to the DDFLOAT version here:

    https://pastebin.com/TdcLJhXP

    Implementation of the NAN? function I leave to users as there several options -
    none of which are easy, portable, and foolproof.-a But I'm always willing to be
    surprised.

    ...


    See https://github.com/mynenik/kForth-32/blob/master/forth-src/ieee-754.4th

    The IEEE proposal, in progress, calls this word FNAN?

    The file linked above provides standard definitions for FNAN? as well as tests for plus and minus infinities and normal and subnormal numbers. There are tests for these words as well.

    Thanks for that. NAN? here however is intended to encompass everything that's not a zero, normal, or subnormal number. I realized the name could be confusing
    but until now it was hidden in my implementations.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From marcel hendrix@mhx@iae.nl to comp.lang.forth on Sun Sep 13 09:00:29 2026
    From Newsgroup: comp.lang.forth

    On 9/12/2026 7:14 PM, dxf wrote:
    dd# 1e-296 ddfs. 1.0000000000000000000000000000000E-296 ok
    dd# 1e-297 ddfs. 1.0000000000000000000000000000000E-297 ok
    [..]
    dd# 1e+300 ddfs. INF ok
    dd# 1e+301 ddfs. INF ok
    \ dd# 1e+302 ddfs. NAN/INF ok
    \ dd# 1e+303 ddfs. NAN/INF ok
    \ dd# 1e+304 ddfs. NAN/INF ok
    \ dd# 1e+305 ddfs. NAN/INF ok

    My interest is only in >DD . I now allow the exponent range [-294,+304]
    (this gives a reasonable mantissa size, e.g.
    FORTH> s" 1000.0e+304 " >dd ddfe. 1.000000000000000000000000000000e307

    Nan/Inf are caught because their dp and/or exponent indicator are
    missing and there are no digits present:
    FORTH> s" nan " >dd ddfe.
    DD :: dp must be `.`
    FORTH> s" -inf " >dd ddfe.
    DD :: dp must be `.`
    FORTH> s" 1e " >dd ddfe. 1.000000000000000000000000000000e0
    FORTH> s" 1.1 " >dd ddfe. 1.100000000000000000000000000000e0 ok
    FORTH> s" 1.1e " >dd ddfe. 1.100000000000000000000000000000e0 ok
    FORTH> s" 1.1e1" >dd ddfe. 1.100000000000000000000000000000e1 ok
    FORTH> 53-bits! s" 1..1e++1" >dd ddfe.
    Error -2
    DD :: not a valid exponent sign ?

    I just noticed these problem:
    FORTH> s" 1" >dd ddfe. 1.000000000000000000000000000000e303 ok
    FORTH> s" 1.1e++1" >dd ddfe. 1.100000000000000000000000000000e0 ok
    FORTH> s" 1.1e+-1" >dd ddfe. 1.100000000000000000000000000000e0 ok
    FORTH> s" 1.1e-+1" >dd ddfe. 1.100000000000000000000000000000e0 ok

    The '.' can be replaced by ',' and the 'e' by 'd' as settable options.

    -marcel
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Sun Sep 13 20:33:30 2026
    From Newsgroup: comp.lang.forth

    On 13/09/2026 5:00 pm, marcel hendrix wrote:
    On 9/12/2026 7:14 PM, dxf wrote:
    dd# 1e-296-a ddfs. 1.0000000000000000000000000000000E-296-a ok
    dd# 1e-297-a ddfs. 1.0000000000000000000000000000000E-297-a ok
    [..]
    dd# 1e+300-a ddfs. INF-a ok
    dd# 1e+301-a ddfs. INF-a ok
    \ dd# 1e+302-a ddfs. NAN/INF-a ok
    \ dd# 1e+303-a ddfs. NAN/INF-a ok
    \ dd# 1e+304-a ddfs. NAN/INF-a ok
    \ dd# 1e+305-a ddfs. NAN/INF-a ok

    My interest is only in >DD . I now allow the exponent range [-294,+304] (this gives a reasonable mantissa size, e.g.
    FORTH> s" 1000.0e+304-a " >dd ddfe.-a 1.000000000000000000000000000000e307

    Nan/Inf are caught because their dp and/or exponent indicator are missing and there are no digits present:
    FORTH> s" nan-a " >dd ddfe.
    DD :: dp must be `.`
    FORTH> s" -inf " >dd ddfe.
    DD :: dp must be `.`
    FORTH> s" 1e-a-a " >dd ddfe.-a 1.000000000000000000000000000000e0
    FORTH> s" 1.1-a " >dd ddfe.-a 1.100000000000000000000000000000e0-a ok
    FORTH> s" 1.1e " >dd ddfe.-a 1.100000000000000000000000000000e0-a ok
    FORTH> s" 1.1e1" >dd ddfe.-a 1.100000000000000000000000000000e1-a ok
    FORTH> 53-bits! s" 1..1e++1" >dd ddfe.
    Error -2
    DD :: not a valid exponent sign ?

    I just noticed these problem:
    FORTH> s" 1"-a-a-a-a-a-a >dd ddfe.-a 1.000000000000000000000000000000e303-a ok
    FORTH> s" 1.1e++1" >dd ddfe.-a 1.100000000000000000000000000000e0-a ok
    FORTH> s" 1.1e+-1" >dd ddfe.-a 1.100000000000000000000000000000e0-a ok
    FORTH> s" 1.1e-+1" >dd ddfe.-a 1.100000000000000000000000000000e0-a ok

    The '.' can be replaced by ',' and the 'e' by 'd' as settable options.

    I assume you're not using my >DD any more. The latter is creating unintended consequences for DDFS. in the form of patches to avoid infinite loops. Either way it's looking messy.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Mon Sep 14 13:28:09 2026
    From Newsgroup: comp.lang.forth

    On 13/09/2026 5:00 pm, marcel hendrix wrote:
    ...
    My interest is only in >DD . I now allow the exponent range [-294,+304] (this gives a reasonable mantissa size, e.g.
    FORTH> s" 1000.0e+304-a " >dd ddfe.-a 1.000000000000000000000000000000e307

    How did you get that? NORMALIZE (even if it doesn't hang) will cause
    1e307 to be converted to NAN NAN and extracting digits from that will
    result in a string of '0's.



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From marcel hendrix@mhx@iae.nl to comp.lang.forth on Mon Sep 14 10:09:32 2026
    From Newsgroup: comp.lang.forth

    On 9/14/2026 5:28 AM, dxf wrote:
    On 13/09/2026 5:00 pm, marcel hendrix wrote:
    ...
    My interest is only in >DD . I now allow the exponent range [-294,+304] (this gives a reasonable mantissa size, e.g.
    FORTH> s" 1000.0e+304-a " >dd ddfe.-a 1.000000000000000000000000000000e307

    How did you get that? NORMALIZE (even if it doesn't hang) will cause
    1e307 to be converted to NAN NAN and extracting digits from that will
    result in a string of '0's.

    Slightly dirty...: normalize ( F: x xx -- |y + yy| ) ( n -- n' )
    ddabs ( F: -- |x + xx| )
    DUP dd=10 dd^n dd/ ( F: -- [|x+xx|]/10^n ) ( -- n )
    BEGIN FOVER 10e F>= \ make sure it's between 1 and 10
    WHILE dd=10 dd/ 1+
    REPEAT
    BEGIN FOVER 1e F< \ make sure it's between 1 and 10
    WHILE dd=10 dd* 1-
    REPEAT ;

    -marcel
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Mon Sep 14 20:00:47 2026
    From Newsgroup: comp.lang.forth

    On 14/09/2026 6:09 pm, marcel hendrix wrote:
    On 9/14/2026 5:28 AM, dxf wrote:
    On 13/09/2026 5:00 pm, marcel hendrix wrote:
    ...
    My interest is only in >DD . I now allow the exponent range [-294,+304] (this gives a reasonable mantissa size, e.g.
    FORTH> s" 1000.0e+304-a " >dd ddfe.-a 1.000000000000000000000000000000e307 >>
    How did you get that?-a NORMALIZE (even if it doesn't hang) will cause
    1e307 to be converted to NAN NAN and extracting digits from that will
    result in a string of '0's.

    Slightly dirty...: normalize ( F: x xx -- |y + yy| ) ( n -- n' ) ddabs-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a ( F: -- |x + xx| )
    -a-a-a-a-a-a-a DUP-a dd=10 dd^n-a dd/-a-a-a ( F: -- [|x+xx|]/10^n ) ( -- n ) -a-a-a-a-a-a-a BEGIN-a-a FOVER 10e F>=-a-a-a \ make sure it's between 1 and 10
    -a-a-a-a-a-a-a WHILE-a-a dd=10 dd/-a 1+
    -a-a-a-a-a-a-a REPEAT
    -a-a-a-a-a-a-a BEGIN-a-a FOVER 1e F<-a-a-a \ make sure it's between 1 and 10 -a-a-a-a-a-a-a WHILE-a-a dd=10 dd*-a 1-
    -a-a-a-a-a-a-a REPEAT ;

    That was enough to cause mine to go into a loop (see below). It was essentially the change I made in 2012 unaware I was introducing an issue.
    I'm using x87 with software stack. Ran it on Gforth (SSE?) and that goes
    into a loop too.


    dd# 1e300 dd# 1e7 dd* ok 1.00000000000002E307 1.39689402397438E290 <f
    ddfs. \ hangs!


    : normalize ( F: x xx -- |y yy| ) ( n -- n' )
    >R
    DDABS
    dd10 R@ DD^N DD/ ( [|x|+|xx|]/10^n )

    \ make sure it's between 1 and 10
    BEGIN FOVER 10e0 F< 0= \ F>
    WHILE dd10 dd/ R> 1+ >R REPEAT

    BEGIN FOVER 1e0 F<
    WHILE dd10 dd* R> 1- >R REPEAT
    R>
    ;

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From marcel hendrix@mhx@iae.nl to comp.lang.forth on Mon Sep 14 12:22:36 2026
    From Newsgroup: comp.lang.forth

    On 9/14/2026 12:00 PM, dxf wrote:
    On 14/09/2026 6:09 pm, marcel hendrix wrote:
    On 9/14/2026 5:28 AM, dxf wrote:
    On 13/09/2026 5:00 pm, marcel hendrix wrote:
    ...
    My interest is only in >DD . I now allow the exponent range [-294,+304] (this gives a reasonable mantissa size, e.g.
    FORTH> s" 1000.0e+304-a " >dd ddfe.-a 1.000000000000000000000000000000e307 >>>
    How did you get that?-a NORMALIZE (even if it doesn't hang) will cause
    1e307 to be converted to NAN NAN and extracting digits from that will
    result in a string of '0's.

    Slightly dirty...: normalize ( F: x xx -- |y + yy| ) ( n -- n' ) ddabs-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a ( F: -- |x + xx| )
    -a-a-a-a-a-a-a DUP-a dd=10 dd^n-a dd/-a-a-a ( F: -- [|x+xx|]/10^n ) ( -- n )
    -a-a-a-a-a-a-a BEGIN-a-a FOVER 10e F>=-a-a-a \ make sure it's between 1 and 10
    -a-a-a-a-a-a-a WHILE-a-a dd=10 dd/-a 1+
    -a-a-a-a-a-a-a REPEAT
    -a-a-a-a-a-a-a BEGIN-a-a FOVER 1e F<-a-a-a \ make sure it's between 1 and 10
    -a-a-a-a-a-a-a WHILE-a-a dd=10 dd*-a 1-
    -a-a-a-a-a-a-a REPEAT ;

    That was enough to cause mine to go into a loop (see below). It was essentially the change I made in 2012 unaware I was introducing an issue.
    I'm using x87 with software stack. Ran it on Gforth (SSE?) and that goes into a loop too.


    dd# 1e300 dd# 1e7 dd* ok 1.00000000000002E307 1.39689402397438E290 <f
    ddfs. \ hangs!


    : normalize ( F: x xx -- |y yy| ) ( n -- n' )
    >R
    DDABS
    dd10 R@ DD^N DD/ ( [|x|+|xx|]/10^n )

    \ make sure it's between 1 and 10
    BEGIN FOVER 10e0 F< 0= \ F>
    WHILE dd10 dd/ R> 1+ >R REPEAT

    BEGIN FOVER 1e0 F<
    WHILE dd10 dd* R> 1- >R REPEAT
    R>
    ;

    Interesting. The way it is written, iForth will execute `FOVER 10e0
    F< 0=` and `FOVER 1e0 F<` on the FPU stack with the full 80 bits. (the
    CPU is in 53-bit mode here, which affects the loading of 10e0 as a 10
    byte constant).

    I made a few tiny changes to the basic dd-fp words that gave me a
    few more valid bits (as seen with the library tests), maybe that is the reason.

    Try insert .S before 10e0 and 1e0 to see what's happening?

    -marcel
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Mon Sep 14 21:59:46 2026
    From Newsgroup: comp.lang.forth

    On 14/09/2026 8:22 pm, marcel hendrix wrote:
    On 9/14/2026 12:00 PM, dxf wrote:
    On 14/09/2026 6:09 pm, marcel hendrix wrote:
    On 9/14/2026 5:28 AM, dxf wrote:
    On 13/09/2026 5:00 pm, marcel hendrix wrote:
    ...
    My interest is only in >DD . I now allow the exponent range [-294,+304] (this gives a reasonable mantissa size, e.g.
    FORTH> s" 1000.0e+304-a " >dd ddfe.-a 1.000000000000000000000000000000e307

    How did you get that?-a NORMALIZE (even if it doesn't hang) will cause >>>> 1e307 to be converted to NAN NAN and extracting digits from that will
    result in a string of '0's.

    Slightly dirty...: normalize ( F: x xx -- |y + yy| ) ( n -- n' ) ddabs-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a ( F: -- |x + xx| )
    -a-a-a-a-a-a-a-a DUP-a dd=10 dd^n-a dd/-a-a-a ( F: -- [|x+xx|]/10^n ) ( -- n )
    -a-a-a-a-a-a-a-a BEGIN-a-a FOVER 10e F>=-a-a-a \ make sure it's between 1 and 10
    -a-a-a-a-a-a-a-a WHILE-a-a dd=10 dd/-a 1+
    -a-a-a-a-a-a-a-a REPEAT
    -a-a-a-a-a-a-a-a BEGIN-a-a FOVER 1e F<-a-a-a \ make sure it's between 1 and 10
    -a-a-a-a-a-a-a-a WHILE-a-a dd=10 dd*-a 1-
    -a-a-a-a-a-a-a-a REPEAT ;

    That was enough to cause mine to go into a loop (see below).-a It was
    essentially the change I made in 2012 unaware I was introducing an issue.
    I'm using x87 with software stack.-a Ran it on Gforth (SSE?) and that goes >> into a loop too.


    dd# 1e300 dd# 1e7 dd* ok-a 1.00000000000002E307 1.39689402397438E290 <f
    ddfs.-a \ hangs!


    : normalize ( F: x xx -- |y yy| ) ( n -- n' )
    -a-a-a-a >R
    -a-a-a-a DDABS
    -a-a-a-a dd10 R@ DD^N-a DD/-a-a-a-a-a-a-a-a-a ( [|x|+|xx|]/10^n )

    -a-a \ make sure it's between 1 and 10
    -a-a-a-a BEGIN-a-a FOVER-a-a 10e0-a F< 0=-a \ F>
    -a-a-a-a WHILE-a-a dd10-a dd/-a R> 1+ >R-a REPEAT

    -a-a-a-a BEGIN-a-a FOVER-a-a 1e0-a-a F<
    -a-a-a-a WHILE-a-a dd10-a dd*-a R> 1- >R-a REPEAT
    -a-a-a-a R>
    ;

    Interesting. The way it is written, iForth will execute `FOVER-a-a 10e0 F< 0=` and `FOVER 1e0 F<` on the FPU stack with the full 80 bits. (the CPU is in 53-bit mode here, which affects the loading of 10e0 as a 10 byte constant).

    I made a few tiny changes to the basic dd-fp words that gave me a
    few more valid bits (as seen with the library tests), maybe that is the reason.

    Try insert .S before 10e0 and 1e0 to see what's happening?

    The looping was caused by NAN 10E F< 0= ... which always returned TRUE. Changing to an integrated F>= cured the looping. The NAN came from:

    ( 1dd307) dd10 307 DD^N DD/ ( NAN NAN)

    Presumably you don't get this (on the FPU stack)?

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From marcel hendrix@mhx@iae.nl to comp.lang.forth on Mon Sep 14 14:26:15 2026
    From Newsgroup: comp.lang.forth

    On 9/14/2026 1:59 PM, dxf wrote:
    On 14/09/2026 8:22 pm, marcel hendrix wrote:
    [..]> The looping was caused by NAN 10E F< 0= ... which always
    returned TRUE.
    Changing to an integrated F>= cured the looping. The NAN came from:
    ( 1dd307) dd10 307 DD^N DD/ ( NAN NAN)

    Presumably you don't get this (on the FPU stack)?

    A NAN can't be compared to anything. I have (ISNAN) and (NOTFIN) to
    detect these patterns. My (DDFE.) is
    \ create memory string for double-double in E-format
    : (DDFE.) ( F: x xx -- ) ( -- c-addr u )
    FOVER F0= IF DDDROP S" 0e" EXIT ENDIF
    FDUP (ISNAN) IF DDDROP S" NaN2" EXIT ENDIF
    FOVER (ISNAN) IF DDDROP S" NaN1" EXIT ENDIF
    FDUP (NOTFIN) IF DDDROP S" Inf" EXIT ENDIF
    FOVER (NOTFIN) IF DDDROP S" Inf" EXIT ENDIF
    getSign ( -- s )
    getPower ( F: x xx -- ) ( -- s n )
    normalize ( F: y yy -- ) ( -- s n' )
    (ddout) F2DROP ;

    At the moment all but one of the bugs I mentioned before are fixed.
    It is not possible to do S" 1" >dd because my >dd wants to see at least
    S" 1." or S" 1e". I don't feel like fixing that (yet).

    There is a weird problem in MATLAB they're not willing to admit is a
    bug. I work around it as it only affects the library accuracy test words
    which are discarded anyway.

    -marcel
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Mon Sep 14 15:00:43 2026
    From Newsgroup: comp.lang.forth

    marcel hendrix <mhx@iae.nl> writes:
    On 9/14/2026 12:00 PM, dxf wrote:
    : normalize ( F: x xx -- |y yy| ) ( n -- n' )
    >R
    DDABS
    dd10 R@ DD^N DD/ ( [|x|+|xx|]/10^n )

    \ make sure it's between 1 and 10
    BEGIN FOVER 10e0 F< 0= \ F>
    WHILE dd10 dd/ R> 1+ >R REPEAT

    BEGIN FOVER 1e0 F<
    WHILE dd10 dd* R> 1- >R REPEAT
    R>
    ;

    Interesting. The way it is written, iForth will execute `FOVER 10e0
    F< 0=` and `FOVER 1e0 F<` on the FPU stack with the full 80 bits. (the
    CPU is in 53-bit mode here, which affects the loading of 10e0 as a 10
    byte constant).

    10e can be represented exactly in FP (any format down to 2 mantissa
    bits and 3 exponent bits, e.g., the 1.3.2 6-bit format <https://en.wikipedia.org/wiki/Minifloat#6-bit_(1.3.2)>), certainly in
    floats of any Forth system. 1e can also be represented exactly in FP
    (0 mantissa bits needed).

    The repeated muliplication and division accumulates rounding errors.
    For more precision, you could do a binary search among powers of 10
    (with the closest DD-FP number where no exact representation is
    available), using either a table or a DD** that is precise to 1/2 ulp.
    Once you have found the power-of-10 range, DD/ the number by the lower
    bound of that range. If it's essential that the result <10e, then
    insert a correction step that checks if the result >=10, and if so,
    replaces that result with 1e and a 1 higher exponent.

    I am debating with myself whether one should use the closest FP number
    with round-to-nearest, or the closest with round-to-absolute-higher.
    Maybe depends on the purpose of this normalization.

    - 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 dxf@dxforth@gmail.com to comp.lang.forth on Tue Sep 15 01:32:06 2026
    From Newsgroup: comp.lang.forth

    On 14/09/2026 10:26 pm, marcel hendrix wrote:
    On 9/14/2026 1:59 PM, dxf wrote:
    On 14/09/2026 8:22 pm, marcel hendrix wrote:
    [..]> The looping was caused by-a NAN 10E F< 0=-a ... which always returned TRUE.
    Changing to an integrated-a F>=-a cured the looping.-a The NAN came from:
    ( 1dd307)-a dd10 307 DD^N-a DD/-a ( NAN NAN)

    Presumably you don't get this (on the FPU stack)?

    A NAN can't be compared to anything. I have (ISNAN) and (NOTFIN) to detect these patterns. My (DDFE.) is
    \ create memory string for double-double in E-format
    : (DDFE.) ( F: x xx -- ) ( -- c-addr u )
    -a-a-a-aFOVER F0=-a-a-a-a-a IF-a DDDROP S"-a 0e"-a-a EXIT-a ENDIF -a-a-a-aFDUP-a (ISNAN)-a IF-a DDDROP S"-a NaN2" EXIT-a ENDIF
    -a-a-a-aFOVER (ISNAN)-a IF-a DDDROP S"-a NaN1" EXIT-a ENDIF
    -a-a-a-aFDUP-a (NOTFIN) IF-a DDDROP S"-a Inf"-a EXIT-a ENDIF
    -a-a-a-aFOVER (NOTFIN) IF-a DDDROP S"-a Inf"-a EXIT-a ENDIF -a-a-a-agetSign-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a ( -- s ) -a-a-a-agetPower-a-a ( F: x xx -- ) ( -- s n-a )
    -a-a-a-anormalize-a ( F: y yy -- ) ( -- s n' )
    -a-a-a-a(ddout)-a-a-a F2DROP ;
    ...

    Those won't handle non-reals generated by NORMALIZE. For DDFS. I've narrowed the issue down to:

    ( 1dd307 1dd307 ) DD/

    It should produce 1dd0 but fails giving NAN NAN instead.

    At the moment all but one of the bugs I mentioned before are fixed.
    It is not possible to do S" 1" >dd because my >dd wants to see at least
    S" 1." or S" 1e". I don't feel like fixing that (yet).

    Since my >DD can't generate 1dd307, I looked into that too:

    ( 1dd0 ) 307 0 ?DO dd10 DD* LOOP

    will fail, producing NAN NAN instead.

    So DD* and DD/ on my system (also Win32Forth, Gforth) are limited to 1E+-300. For various reasons unrelated to the code you seem to be getting somewhat better results.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From marcel hendrix@mhx@iae.nl to comp.lang.forth on Mon Sep 14 21:08:28 2026
    From Newsgroup: comp.lang.forth

    On 9/14/2026 5:32 PM, dxf wrote:
    Those won't handle non-reals generated by NORMALIZE. For DDFS. I've narrowed the issue down to:

    ( 1dd307 1dd307 ) DD/

    It should produce 1dd0 but fails giving NAN NAN instead.


    Well, I can't use >DD with 1e307:

    FORTH> S" 1e307" >dd dddup dd/ ddfe.
    DD :: exponent too large or too small

    Since my >DD can't generate 1dd307, I looked into that too:

    ( 1dd0 ) 307 0 ?DO dd10 DD* LOOP

    will fail, producing NAN NAN instead.

    Using your workaround:

    FORTH> S" 1e303" >dd S" 1e4" >dd dd* dddup dd/ ddfe. 1.000000000000000000000000000000e0 ok

    So DD/ is not a problem here.

    Also
    FORTH> S" 100000e303" >dd dddup dd/ ddfe.
    1.000000000000000000000000000000e0 ok

    But 1e309 of course generates a NAN ( which is caught by DDFE. and shown
    as "NaN2" )
    FORTH> S" 1e303" >dd S" 1e6" >dd dd* dddup dd/ ddfe. NaN2 ok

    So DD* and DD/ on my system (also Win32Forth, Gforth) are limited to 1E+-300. For various reasons unrelated to the code you seem to be getting somewhat better results.

    The plain limit here is currently
    FORTH> S" 1e304" >dd
    DD :: exponent too large or too small

    That is because I want to be able to write
    FORTH> S" 10000e303" >dd ddfe. 1.000000000000000000000000000000e307

    IMO, for all practical purposes this is more than sufficient.

    -marcel
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From marcel hendrix@mhx@iae.nl to comp.lang.forth on Mon Sep 14 21:15:37 2026
    From Newsgroup: comp.lang.forth

    On 9/14/2026 5:00 PM, Anton Ertl wrote:
    I am debating with myself whether one should use the closest FP number
    with round-to-nearest, or the closest with round-to-absolute-higher.
    Maybe depends on the purpose of this normalization.

    Yes, that is an interesting question that might, e.g., pop up for the
    next generation metacompilers (generating 128 bits code on a 64 bit
    Forth that can't generate itself yet). I don't know if I will live to
    see it. Maybe when quantum-state memory is invented next month by our AI overlords.

    -marcel
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Mon Sep 14 15:25:51 2026
    From Newsgroup: comp.lang.forth

    On 9/14/26 2:08 PM, marcel hendrix wrote:
    On 9/14/2026 5:32 PM, dxf wrote:
    ...
    The plain limit here is currently
    FORTH> S" 1e304" >dd
    DD :: exponent too large or too small

    That is because I want to be able to write
    FORTH> S" 10000e303" >dd ddfe. 1.000000000000000000000000000000e307

    IMO, for all practical purposes this is more than sufficient.

    Yet, one should check whether or not it's technically correct for double-double arithmetic.

    We need to go back to Bailey's ddfun package to see how he did the >DD conversion.

    My two cents.

    --
    KM

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Mon Sep 14 15:29:15 2026
    From Newsgroup: comp.lang.forth

    On 9/14/26 10:00 AM, Anton Ertl wrote:
    ...

    I am debating with myself whether one should use the closest FP number
    with round-to-nearest, or the closest with round-to-absolute-higher.
    Maybe depends on the purpose of this normalization.

    Is your idea to stay within 1 ulp error for the conversion, but use a
    simpler algorithm?

    --
    KM

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Mon Sep 14 20:58:16 2026
    From Newsgroup: comp.lang.forth

    Krishna Myneni <krishna.myneni@ccreweb.org> writes:
    On 9/14/26 10:00 AM, Anton Ertl wrote:
    ...

    I am debating with myself whether one should use the closest FP number
    with round-to-nearest, or the closest with round-to-absolute-higher.
    Maybe depends on the purpose of this normalization.

    Is your idea to stay within 1 ulp error for the conversion, but use a >simpler algorithm?

    No.

    The idea here is as follows:

    You have your number X that you want to normalize to a power of 10.
    For that number there exist numbers Y, Y', Z, and Z', where

    Y > X >= Z
    Y >= 10^(n+1) > prev(Y)
    Z >= 10^n > prev(Z)

    Where prev(V) produces the largest (in absolute terms) FP value <V.
    So Y or Z are either powers of 10 or the smallest FP numbers just
    above a power of 10, and they are those numbers which are the
    normalization boundaries of X.

    For normalizing X, we would love to divide by 10^n, but if that's not representable as FP number, and if we want to use our FP words to do
    that, what do we use?

    1) The result that has the best chance of being close to the proper
    result would be to use the FP number Z' that's closest to 10^n (round
    to nearest). But if Z'=prev(Z) (which will probably be the case half
    of the time when 10^n cannot be represented exactly), the result of
    X/Z' will be larger than it should be, and, in particular, even if
    X=Z, X/Z' might have a value >1.0, which is probably not desired.

    2) Instead, you could normalize as X/Z, i.e., the number that's
    closest to 10^n if you round away from 0 (what I described as round-to-absolute-higher above). But Z can be up to 1ulp away from
    10^n, so the result of X/Z will, on averge be further from the
    intended value than X/Z'.

    Another option is to normalize in a more precise way than performing a double-double FP multiplication or division, but that's more costly.

    - 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 dxf@dxforth@gmail.com to comp.lang.forth on Tue Sep 15 13:11:11 2026
    From Newsgroup: comp.lang.forth

    On 15/09/2026 6:25 am, Krishna Myneni wrote:
    On 9/14/26 2:08 PM, marcel hendrix wrote:
    On 9/14/2026 5:32 PM, dxf wrote:
    ...
    The plain limit here is currently
    FORTH> S" 1e304" >dd
    DD :: exponent too large or too small

    That is because I want to be able to write
    FORTH> S" 10000e303" >dd ddfe. 1.000000000000000000000000000000e307

    IMO, for all practical purposes this is more than sufficient.

    Yet, one should check whether or not it's technically correct for double-double arithmetic.

    We need to go back to Bailey's ddfun package to see how he did the >DD conversion.

    My two cents.

    On regular double-precision systems the limitation will be DD* DD/ which
    makes 10^307 math impractical irrespective of >DD . I suspect Marcel's
    80-bit intermediates/variables is giving him a bit more range.

    FWIW my latest version is here:

    https://pastebin.com/bcbFUZF0

    Numbers out of range will be printed as **DD** . Bug reports welcome.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From marcel hendrix@mhx@iae.nl to comp.lang.forth on Tue Sep 15 14:06:01 2026
    From Newsgroup: comp.lang.forth

    On 9/15/2026 5:11 AM, dxf wrote:
    On 15/09/2026 6:25 am, Krishna Myneni wrote:
    On 9/14/26 2:08 PM, marcel hendrix wrote:
    On 9/14/2026 5:32 PM, dxf wrote:
    ...
    The plain limit here is currently
    FORTH> S" 1e304" >dd
    DD :: exponent too large or too small

    That is because I want to be able to write
    FORTH> S" 10000e303" >dd ddfe. 1.000000000000000000000000000000e307

    IMO, for all practical purposes this is more than sufficient.

    Yet, one should check whether or not it's technically correct for double-double arithmetic.

    We need to go back to Bailey's ddfun package to see how he did the >DD conversion.

    My two cents.

    On regular double-precision systems the limitation will be DD* DD/ which makes 10^307 math impractical irrespective of >DD . I suspect Marcel's 80-bit intermediates/variables is giving him a bit more range.

    FWIW my latest version is here:

    https://pastebin.com/bcbFUZF0

    Numbers out of range will be printed as **DD** . Bug reports welcome.

    General remarks:
    D. Bailey has authored a quad-double package with 211 significant bits.
    Did anybody look into this yet?

    Double-double might be doable with 64bit (extended) floats. That would
    make guarding the FPU control word around exceptions much easier.

    -marcel
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Tue Sep 15 07:33:55 2026
    From Newsgroup: comp.lang.forth

    On 9/14/26 3:58 PM, Anton Ertl wrote:
    Krishna Myneni <krishna.myneni@ccreweb.org> writes:
    On 9/14/26 10:00 AM, Anton Ertl wrote:
    ...

    I am debating with myself whether one should use the closest FP number
    with round-to-nearest, or the closest with round-to-absolute-higher.
    Maybe depends on the purpose of this normalization.

    Is your idea to stay within 1 ulp error for the conversion, but use a
    simpler algorithm?

    No.

    The idea here is as follows:

    You have your number X that you want to normalize to a power of 10.
    For that number there exist numbers Y, Y', Z, and Z', where

    Y > X >= Z
    Y >= 10^(n+1) > prev(Y)
    Z >= 10^n > prev(Z)

    Where prev(V) produces the largest (in absolute terms) FP value <V.
    So Y or Z are either powers of 10 or the smallest FP numbers just
    above a power of 10, and they are those numbers which are the
    normalization boundaries of X.

    For normalizing X, we would love to divide by 10^n, but if that's not representable as FP number, and if we want to use our FP words to do
    that, what do we use?

    1) The result that has the best chance of being close to the proper
    result would be to use the FP number Z' that's closest to 10^n (round
    to nearest). But if Z'=prev(Z) (which will probably be the case half
    of the time when 10^n cannot be represented exactly), the result of
    X/Z' will be larger than it should be, and, in particular, even if
    X=Z, X/Z' might have a value >1.0, which is probably not desired.

    2) Instead, you could normalize as X/Z, i.e., the number that's
    closest to 10^n if you round away from 0 (what I described as round-to-absolute-higher above). But Z can be up to 1ulp away from
    10^n, so the result of X/Z will, on averge be further from the
    intended value than X/Z'.

    Another option is to normalize in a more precise way than performing a double-double FP multiplication or division, but that's more costly.


    The present implementation of >DD decimal string to double-double
    conversion in kForth (dd_io.4th) is off by 14 ulp for the case of pi,
    which is not good enough, so it will be useful to compare your proposed conversion procedure.

    \ For 64-bit Forth with a separate fp stack

    3.1415926535897931e0 1.2246467991473532e-16 ddconstant ddpi

    32 set-precision
    ddpi ddfs.
    +3.1415926535897932384626433832795 dd 0 ok

    ddvariable ref
    ddvariable cnv

    ddpi ref dd! \ reference
    \ convert decimal string to double double with >DD
    S" 3.1415926535897932384626433832795dd0" >dd cnv dd!

    cnv dd@ ddfs.
    +3.1415926535897932384626433832791 dd 0 ok

    17 set-precision
    \ print high and low double precision fp numbers
    ref dd@ fswap fs. 2 spaces fs.
    3.1415926535897931e+00 1.2246467991473532e-16 ok
    cnv dd@ fswap fs. 2 spaces fs.
    3.1415926535897931e+00 1.2246467991473498e-16 ok

    \ Note the loss of significant digits in the low double for cnv
    \ What is the ulp error for cnv?
    hex
    ref 8 + @ u. \ print the 64-bit hex value of ref, low double
    3CA1A62633145C07 ok
    cnv 8 + @ u. \ print the 64-bit hex value of cnv, low double
    3CA1A62633145BF9 ok

    \ difference in ulp
    decimal
    cnv 8 + @ ref 8 + @ - .
    -14 ok

    --
    Krishna




    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Wed Sep 16 00:05:39 2026
    From Newsgroup: comp.lang.forth

    On 15/09/2026 1:11 pm, dxf wrote:
    On 15/09/2026 6:25 am, Krishna Myneni wrote:
    On 9/14/26 2:08 PM, marcel hendrix wrote:
    On 9/14/2026 5:32 PM, dxf wrote:
    ...
    The plain limit here is currently
    FORTH> S" 1e304" >dd
    DD :: exponent too large or too small

    That is because I want to be able to write
    FORTH> S" 10000e303" >dd ddfe. 1.000000000000000000000000000000e307

    IMO, for all practical purposes this is more than sufficient.

    Yet, one should check whether or not it's technically correct for double-double arithmetic.

    We need to go back to Bailey's ddfun package to see how he did the >DD conversion.

    My two cents.

    On regular double-precision systems the limitation will be DD* DD/ which makes 10^307 math impractical irrespective of >DD . I suspect Marcel's 80-bit intermediates/variables is giving him a bit more range.

    FWIW my latest version is here:

    https://pastebin.com/bcbFUZF0

    Numbers out of range will be printed as **DD** . Bug reports welcome.

    DDFLOAT 2026-09-16

    Bugfix: could print junk instead of **DD**

    https://pastebin.com/HqPtRMDH

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Tue Sep 15 15:53:03 2026
    From Newsgroup: comp.lang.forth

    Krishna Myneni <krishna.myneni@ccreweb.org> writes:
    The present implementation of >DD decimal string to double-double
    conversion in kForth (dd_io.4th) is off by 14 ulp for the case of pi,
    which is not good enough, so it will be useful to compare your proposed >conversion procedure.

    I did not propose a conversion procedure, only an approach to
    implementing NORMALIZE. I think that NORMALIZE may be useful for DD
    to string conversion, not the other way round.

    - 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 Tue Sep 15 15:23:24 2026
    From Newsgroup: comp.lang.forth

    On 9/15/26 10:53 AM, Anton Ertl wrote:
    Krishna Myneni <krishna.myneni@ccreweb.org> writes:
    The present implementation of >DD decimal string to double-double
    conversion in kForth (dd_io.4th) is off by 14 ulp for the case of pi,
    which is not good enough, so it will be useful to compare your proposed
    conversion procedure.

    I did not propose a conversion procedure, only an approach to
    implementing NORMALIZE. I think that NORMALIZE may be useful for DD
    to string conversion, not the other way round.


    I misunderstood what you were saying.

    There is a problem for converting in both directions. This is why I now
    use dtoa.c for coversions involving double precision floating point
    numbers, in both directions, across all kForth implementations.

    Simple band aids are not a long-term solution.

    --
    KM
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Tue Sep 15 17:53:42 2026
    From Newsgroup: comp.lang.forth

    On 9/15/26 3:23 PM, Krishna Myneni wrote:
    On 9/15/26 10:53 AM, Anton Ertl wrote:
    Krishna Myneni <krishna.myneni@ccreweb.org> writes:
    The present implementation of >DD decimal string to double-double
    conversion in kForth (dd_io.4th) is off by 14 ulp for the case of pi,
    which is not good enough, so it will be useful to compare your proposed
    conversion procedure.

    I did not propose a conversion procedure, only an approach to
    implementing NORMALIZE.-a I think that NORMALIZE may be useful for DD
    to string conversion, not the other way round.


    I misunderstood what you were saying.

    There is a problem for converting in both directions. This is why I now
    use dtoa.c for coversions involving double precision floating point
    numbers, in both directions, across all kForth implementations.

    Simple band aids are not a long-term solution.


    To be clear, I think there should exist equivalent Forth code for accomplishing the conversions, both for double-precision and for
    double-double precision. But it helps to get there by using proven
    existing code from other languages as a reference against which to check
    any Forth implementations.

    Also, I'm not against band aids for getting partially working code for
    use in the short term.

    --
    KM


    --- Synchronet 3.22a-Linux NewsLink 1.2