• IEEE floating point comparisons

    From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Sun May 3 22:00:56 2026
    From Newsgroup: comp.lang.forth

    Below is preliminary test code for floating point comparisons for
    systems with expected IEEE 754 behavior.

    Relevant floating point exceptions should be masked.

    Please let me know if you find any errors in the tests.

    The tests pass on recent kForth-32/64 development versions (v2.8.0 and
    v0.8.0, respectively):
    TESTING F=
    TESTING F<>
    TESTING F<
    TESTING F>
    TESTING F<=
    TESTING F>=
    TESTING F0=
    TESTING F0<
    TESTING F0>

    The auxiliary code, ieee-754.4th, which defines special values is also attached below.

    --
    Krishna Myneni

    2 attachments:

    ieee-comparisons-test.4th
    ieee-754.4th

    \ ===== begin ieee-comparisons-test.4th =====
    \ ieee-comparisons-test.4th
    \
    \ Comparison of IEEE 754 special values
    \ Floating point exceptions should be masked.
    \
    \ include ans-words.4th (needed for kForth only)
    include ttester.4th
    include ieee-754.4th

    TESTING F=
    \ F= sanity tests
    t{ -1e -1e F= -> true }t
    t{ -1e 1e F= -> false }t
    t{ 1e -1e F= -> false }t
    t{ 1e 1e F= -> true }t

    \ F= NAN tests
    t{ +NAN +NAN F= -> false }t
    t{ +NAN -NAN F= -> false }t
    t{ +NAN +INF F= -> false }t
    t{ -NAN +INF F= -> false }t
    t{ +NAN -INF F= -> false }t
    t{ -NAN -INF F= -> false }t
    t{ +NAN 0e F= -> false }t
    t{ -NAN 0e F= -> false }t
    t{ +NAN -0e F= -> false }t
    t{ -NAN -0e F= -> false }t

    \ F= +/-0 and +/-INF tests
    t{ -0e -0e F= -> true }t
    t{ -0e 0e F= -> true }t
    t{ 0e -0e F= -> true }t
    t{ 0e 0e F= -> true }t
    t{ -INF -0e F= -> false }t
    t{ -INF 0e F= -> false }t
    t{ +INF -0e F= -> false }t
    t{ +INF 0e F= -> false }t
    t{ +INF -INF F= -> false }t
    t{ +INF +INF F= -> true }t
    t{ -INF -INF F= -> true }t
    t{ -INF +INF F= -> false }t


    TESTING F<>
    \ F<> sanity tests
    t{ -1e -1e F<> -> false }t
    t{ -1e 1e F<> -> true }t
    t{ 1e -1e F<> -> true }t
    t{ 1e 1e F<> -> false }t

    \ F<> NAN tests
    t{ +NAN +NAN F<> -> true }t
    t{ +NAN -NAN F<> -> true }t
    t{ +NAN +INF F<> -> true }t
    t{ -NAN +INF F<> -> true }t
    t{ +NAN -INF F<> -> true }t
    t{ -NAN -INF F<> -> true }t
    t{ +NAN 0e F<> -> true }t
    t{ -NAN 0e F<> -> true }t
    t{ +NAN -0e F<> -> true }t
    t{ -NAN -0e F<> -> true }t

    \ F<> +/-0 and +/-INF tests
    t{ -0e -0e F<> -> false }t
    t{ -0e 0e F<> -> false }t
    t{ 0e -0e F<> -> false }t
    t{ 0e 0e F<> -> false }t
    t{ -INF -0e F<> -> true }t
    t{ -INF 0e F<> -> true }t
    t{ +INF -0e F<> -> true }t
    t{ +INF 0e F<> -> true }t
    t{ +INF -INF F<> -> true }t
    t{ +INF +INF F<> -> false }t
    t{ -INF -INF F<> -> false }t
    t{ -INF +INF F<> -> true }t


    TESTING F<
    \ F< sanity tests
    t{ -1e -1e F< -> false }t
    t{ -1e 1e F< -> true }t
    t{ 1e -1e F< -> false }t
    t{ 1e 1e F< -> false }t

    \ F< NAN tests
    t{ +NAN +NAN F< -> false }t
    t{ +NAN -NAN F< -> false }t
    t{ +NAN +INF F< -> false }t
    t{ -NAN +INF F< -> false }t
    t{ +NAN -INF F< -> false }t
    t{ -NAN -INF F< -> false }t
    t{ +NAN 0e F< -> false }t
    t{ -NAN 0e F< -> false }t
    t{ +NAN -0e F< -> false }t
    t{ -NAN -0e F< -> false }t

    \ F< +/-0 and +/-INF tests
    t{ -0e -0e F< -> false }t
    t{ -0e 0e F< -> false }t
    t{ 0e -0e F< -> false }t
    t{ 0e 0e F< -> false }t
    t{ -INF -0e F< -> true }t
    t{ -INF 0e F< -> true }t
    t{ +INF -0e F< -> false }t
    t{ +INF 0e F< -> false }t
    t{ +INF -INF F< -> false }t
    t{ +INF +INF F< -> false }t
    t{ -INF -INF F< -> false }t
    t{ -INF +INF F< -> true }t


    TESTING F>
    \ F> sanity tests
    t{ -1e -1e F> -> false }t
    t{ -1e 1e F> -> false }t
    t{ 1e -1e F> -> true }t
    t{ 1e 1e F> -> false }t

    \ F> NAN tests
    t{ +NAN +NAN F> -> false }t
    t{ +NAN -NAN F> -> false }t
    t{ +NAN +INF F> -> false }t
    t{ -NAN +INF F> -> false }t
    t{ +NAN -INF F> -> false }t
    t{ -NAN -INF F> -> false }t
    t{ +NAN 0e F> -> false }t
    t{ -NAN 0e F> -> false }t
    t{ +NAN -0e F> -> false }t
    t{ -NAN -0e F> -> false }t

    \ F> +/-0 and +/-INF tests
    t{ -0e -0e F> -> false }t
    t{ -0e 0e F> -> false }t
    t{ 0e -0e F> -> false }t
    t{ 0e 0e F> -> false }t
    t{ -INF -0e F> -> false }t
    t{ -INF 0e F> -> false }t
    t{ +INF -0e F> -> true }t
    t{ +INF 0e F> -> true }t
    t{ +INF -INF F> -> true }t
    t{ +INF +INF F> -> false }t
    t{ -INF -INF F> -> false }t
    t{ -INF +INF F> -> false }t


    TESTING F<=
    \ F<= sanity tests
    t{ -1e -1e F<= -> true }t
    t{ -1e 1e F<= -> true }t
    t{ 1e -1e F<= -> false }t
    t{ 1e 1e F<= -> true }t

    \ F<= NAN tests
    t{ +NAN +NAN F<= -> false }t
    t{ +NAN -NAN F<= -> false }t
    t{ +NAN +INF F<= -> false }t
    t{ -NAN +INF F<= -> false }t
    t{ +NAN -INF F<= -> false }t
    t{ -NAN -INF F<= -> false }t
    t{ +NAN 0e F<= -> false }t
    t{ -NAN 0e F<= -> false }t
    t{ +NAN -0e F<= -> false }t
    t{ -NAN -0e F<= -> false }t

    \ F<= +/-0 and +/-INF tests
    t{ -0e -0e F<= -> true }t
    t{ -0e 0e F<= -> true }t
    t{ 0e -0e F<= -> true }t
    t{ 0e 0e F<= -> true }t
    t{ -INF -0e F<= -> true }t
    t{ -INF 0e F<= -> true }t
    t{ +INF -0e F<= -> false }t
    t{ +INF 0e F<= -> false }t
    t{ +INF -INF F<= -> false }t
    t{ +INF +INF F<= -> true }t
    t{ -INF -INF F<= -> true }t
    t{ -INF +INF F<= -> true }t


    TESTING F>=
    \ F>= sanity tests
    t{ -1e -1e F>= -> true }t
    t{ -1e 1e F>= -> false }t
    t{ 1e -1e F>= -> true }t
    t{ 1e 1e F>= -> true }t

    \ F>= NAN tests
    t{ +NAN +NAN F>= -> false }t
    t{ +NAN -NAN F>= -> false }t
    t{ +NAN +INF F>= -> false }t
    t{ -NAN +INF F>= -> false }t
    t{ +NAN -INF F>= -> false }t
    t{ -NAN -INF F>= -> false }t
    t{ +NAN 0e F>= -> false }t
    t{ -NAN 0e F>= -> false }t
    t{ +NAN -0e F>= -> false }t
    t{ -NAN -0e F>= -> false }t

    \ F>= +/-0 and +/-INF tests
    t{ -0e -0e F>= -> true }t
    t{ -0e 0e F>= -> true }t
    t{ 0e -0e F>= -> true }t
    t{ 0e 0e F>= -> true }t
    t{ -INF -0e F>= -> false }t
    t{ -INF 0e F>= -> false }t
    t{ +INF -0e F>= -> true }t
    t{ +INF 0e F>= -> true }t
    t{ +INF -INF F>= -> true }t
    t{ +INF +INF F>= -> true }t
    t{ -INF -INF F>= -> true }t
    t{ -INF +INF F>= -> false }t


    TESTING F0=
    \ F0= NAN tests
    t{ +NAN F0= -> false }t
    t{ -NAN F0= -> false }t

    TESTING F0<
    \ F0< NAN tests
    t{ +NAN F0< -> false }t
    t{ -NAN F0< -> false }t

    TESTING F0>
    \ F0> NAN tests
    t{ +NAN F0> -> false }t
    t{ -NAN F0> -> false }t

    \ ===== end ieee-comparisons-test.4th =====


    \ ===== begin ieee-754.4th =====
    \ ieee-754.4th
    \
    \ Provides additional definitions for IEEE 754 double-precision
    \ floating point arithmetic on x87 FPU.
    \
    \ GLOSSARY:
    \
    \ Generic construction of a double-precision float from its
    \ binary fields:
    \
    \ MAKE-IEEE-DFLOAT ( signbit udfraction uexp -- r nerror )
    \ ( signbit udfraction uexp -- nerror ) ( F: -- r)
    \
    \ Binary fields of IEEE 754 floating point values
    \
    \ FSIGNBIT ( F: r -- ) ( -- minus? )
    \ FEXPONENT ( F: r -- ) ( -- uexp )
    \ FFRACTION ( F: r -- ) ( -- udfraction )
    \
    \ FINITE? ( F: r -- ) ( -- flag )
    \ FNORMAL? ( F: r -- ) ( -- flag )
    \ FSUBNORMAL? ( F: r -- ) ( -- flag )
    \ FINFINITE? ( F: r -- ) ( -- flag )
    \ FNAN? ( F: r -- ) ( -- flag )
    \
    \ Exception flag words
    \
    \ GET-FFLAGS ( excpts -- flags )
    \ CLEAR-ALL-FFLAGS ( -- )
    \
    \ IEEE 754 special values:
    \
    \ +INF ( F: -- r )
    \ -INF ( F: -- r )
    \ +NAN ( F: -- r )
    \ -NAN ( F: -- r )
    \
    \ To be implemented:
    \
    \ FCOPYSIGN ( F: r1 r2 -- r3 )
    \ FNEARBYINT ( F: r1 -- r2 )
    \ FNEXTUP ( F: r1 -- r2 )
    \ FNEXTDOWN ( F: r1 -- r2 )
    \ FSCALBN ( n -- ) ( F: r -- r*2^n )
    \ FLOGB ( F: r -- e )
    \ FREMAINDER ( F: x y -- r q )
    \ CLEAR-FFLAGS ( excepts -- )
    \ SET-FFLAGS ( excepts -- )
    \ FENABLE ( excepts -- )
    \ FDISABLE ( excepts -- )
    \
    \
    \ These words are based on the Optional IEEE 754 Binary Floating
    \ Point word set(s) proposed by David N. Williams [1]. A few of
    \ the words provided here are additional convenience words which
    \ are not part of the proposals in Ref. 1.
    \
    \ K. Myneni, 2020-08-20
    \ Revs. 2020-08-27, 2022-08-02, 2026-02-08
    \
    \ References:
    \ 1. David N. Williams, Proposal Drafts for Optional IEEE 754
    \ Binary Floating Point Word Set, 27 August 2020.
    \ http://www-personal.umich.edu/~williams/archive/forth/ieeefp-drafts/
    \
    BASE @
    DECIMAL
    0e fconstant F=ZERO
    HEX


    \ Make an IEEE 754 double precision floating point value from
    \ the specified bits for the sign, binary fraction, and exponent.
    \ Return the fp value and error code with the following meaning:
    \ 0 no error
    \ 1 exponent out of range
    \ 2 fraction out of range
    fvariable temp

    : MAKE-IEEE-DFLOAT ( signbit udfraction uexp -- r nerror )
    dup 800 u< invert IF 2drop 2drop F=ZERO 1 EXIT THEN
    14 lshift 3 pick 1F lshift or >r
    dup 100000 u< invert IF
    r> 2drop 2drop F=ZERO 2 EXIT
    THEN
    r> or [ temp 4 + ] literal L! temp L!
    drop temp df@ 0 ;

    : FSIGNBIT ( F: r -- ) ( -- minus? )
    temp df! [ temp 4 + ] literal UL@ 80000000 and 0<> ;

    : FEXPONENT ( F: r -- ) ( -- u )
    temp df! [ temp 4 + ] literal UL@ 14 rshift 7FF and ;

    : FFRACTION ( F: r -- ) ( -- ud )
    temp df! temp UL@ [ temp 4 + ] literal UL@ 000FFFFF and ;

    : FINITE? ( F: r -- ) ( -- [normal|subnormal]? ) fexponent 7FF <> ;

    : FNORMAL? ( F: r -- ) ( -- normal? ) fexponent 0<> ;

    : FSUBNORMAL? ( F: r -- ) ( -- subnormal? ) fexponent 0= ;

    : FINFINITE? ( F: r -- ) ( -- [+/-]Inf? )
    finite? invert ;

    : FNAN? ( F: r -- ) ( -- nan? )
    fdup FEXPONENT 7FF = >r FFRACTION D0= invert r> and ;


    \ Exception bits in fpu status word

    1 constant FINVALID
    4 constant FDIVBYZERO
    8 constant FOVERFLOW
    10 constant FUNDERFLOW
    20 constant FINEXACT

    FINVALID FDIVBYZERO or FOVERFLOW or FUNDERFLOW or FINEXACT or
    constant ALL-FEXCEPTS

    1 cells 4 = [IF]

    [DEFINED] getFPUstatusX86 [IF]

    : GET-FFLAGS ( excepts -- flags )
    getFPUstatusX86 fpu-status @ and ;

    : CLEAR-ALL-FFLAGS ( -- ) clearFPUexceptionsX86 ;

    : CLEAR-FFLAGS ( excepts -- )
    ;

    : SET-FFLAGS ( excepts -- )
    ;

    : FENABLE ( excepts -- )
    ;

    : FDISABLE ( excepts -- )
    ;

    : FCOPYSIGN ( F: r1 r2 -- r3 )
    ;

    : FNEARBYINT ( F: r1 -- r2 )
    ;

    : FNEXTUP ( F: r1 -- r2 )
    ;

    : FNEXTDOWN ( F: r1 -- r2 )
    ;

    : FSCALBN ( r n -- r*2^n )
    ;

    : FLOGB ( F: r -- e )
    ;

    : FREMAINDER ( F: x y -- r q )

    ;
    [ELSE]
    cr .( Some functions are not available.) cr
    [THEN]
    [ELSE]
    cr .( Some functions are for 32-bit system only!) cr
    [THEN]

    \ Constants representing -INF +INF -NAN +NAN
    true 0 0 7FF make-ieee-dfloat 0= [IF] fconstant -INF [ELSE] fdrop [THEN] [DEFINED] -INF [IF] -INF fnegate fconstant +INF [THEN]
    true 1 0 7FF make-ieee-dfloat 0= [IF] fconstant -NAN [ELSE] fdrop [THEN] [DEFINED] -NAN [IF] -NAN fnegate fconstant +NAN [THEN]


    BASE !
    \ ===== end ieee-754.4th =====

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Sun May 3 22:18:28 2026
    From Newsgroup: comp.lang.forth

    On 5/3/26 10:00 PM, Krishna Myneni wrote:
    Below is preliminary test code for floating point comparisons for
    systems with expected IEEE 754 behavior.

    ...

    Looking back through David N Williams' archive from his personal page at umich.edu, I found test code for his reference implementation of IEEE fp
    words from ieee-ref-test.fs, version 0.5.0 from December 24, 2020:

    ( Title: Tests for IEEE 754-2008 reference representation
    File: ieeefp-ref-test.fs
    Author: David N. Williams
    Version: 0.5.0
    License: Public Domain
    Revised: December 24, 2020
    ...

    The above code is much more comprehensive and complex than the tests I
    post here. I did not use them as a reference for writing my ieee-comparisons-test.4th, which is much more limited in scope.

    If anyone has a later version of David's reference implementation and
    tests, I would appreciate you sending those to me.

    --
    KM

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From peter@peter.noreply@tin.it to comp.lang.forth on Mon May 4 09:43:59 2026
    From Newsgroup: comp.lang.forth

    On Sun, 3 May 2026 22:00:56 -0500
    Krishna Myneni <krishna.myneni@ccreweb.org> wrote:

    Below is preliminary test code for floating point comparisons for
    systems with expected IEEE 754 behavior.

    Relevant floating point exceptions should be masked.

    Please let me know if you find any errors in the tests.

    The tests pass on recent kForth-32/64 development versions (v2.8.0 and v0.8.0, respectively):
    TESTING F=
    TESTING F<>
    TESTING F<
    TESTING F>
    TESTING F<=
    TESTING F>=
    TESTING F0=
    TESTING F0<
    TESTING F0>

    The auxiliary code, ieee-754.4th, which defines special values is also attached below.

    --
    Krishna Myneni

    2 attachments:

    ieee-comparisons-test.4th
    ieee-754.4th

    \ ===== begin ieee-comparisons-test.4th =====
    \ ieee-comparisons-test.4th
    \
    \ Comparison of IEEE 754 special values
    \ Floating point exceptions should be masked.
    \
    \ include ans-words.4th (needed for kForth only)
    include ttester.4th
    include ieee-754.4th


    Tested it on lxf64. No errors reported!

    I needed to define +NAN and +INF, I had them as NAN and INF.
    But I print them out as +INF etc! It makes more sense with the +

    I did not include the ieee-754.4th as that did not add anything.

    on lxf there is a problem with f<> and NANs. I need to correct f<>

    BR
    Peter

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Mon May 4 07:29:12 2026
    From Newsgroup: comp.lang.forth

    On 5/4/26 02:43, peter wrote:
    On Sun, 3 May 2026 22:00:56 -0500
    Krishna Myneni <krishna.myneni@ccreweb.org> wrote:

    Below is preliminary test code for floating point comparisons for
    systems with expected IEEE 754 behavior.

    Relevant floating point exceptions should be masked.

    Please let me know if you find any errors in the tests.

    The tests pass on recent kForth-32/64 development versions (v2.8.0 and
    v0.8.0, respectively):
    TESTING F=
    TESTING F<>
    TESTING F<
    TESTING F>
    TESTING F<=
    TESTING F>=
    TESTING F0=
    TESTING F0<
    TESTING F0>

    The auxiliary code, ieee-754.4th, which defines special values is also
    attached below.

    --
    Krishna Myneni

    2 attachments:

    ieee-comparisons-test.4th
    ieee-754.4th

    \ ===== begin ieee-comparisons-test.4th =====
    \ ieee-comparisons-test.4th
    \
    \ Comparison of IEEE 754 special values
    \ Floating point exceptions should be masked.
    \
    \ include ans-words.4th (needed for kForth only)
    include ttester.4th
    include ieee-754.4th


    Tested it on lxf64. No errors reported!

    I needed to define +NAN and +INF, I had them as NAN and INF.
    But I print them out as +INF etc! It makes more sense with the +

    I did not include the ieee-754.4th as that did not add anything.

    on lxf there is a problem with f<> and NANs. I need to correct f<>
    ...

    Good to hear.

    I included ieee-754.4th for Forth systems which did not have +/-INF and
    +/-NAN defined. It also provides the extremely useful words FINFINITE?
    and FNAN? to check for infinities and NANs resulting from calculations,
    as well as FSUBNORMAL? when the results are represented with less
    precision than standard double precision. These words are all part of
    David Williams' IEEE proposal.

    The rationale for the signed NAN is unclear to me, but I think David had
    a good reason to include it in his IEEE proposal. It may be useful in
    some numerical computation cases. I will look into this further.

    --
    Krishna
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From minforth@minforth@gmx.net to comp.lang.forth on Mon May 4 21:53:10 2026
    From Newsgroup: comp.lang.forth

    Am 04.05.2026 um 14:29 schrieb Krishna Myneni:
    On 5/4/26 02:43, peter wrote:
    On Sun, 3 May 2026 22:00:56 -0500
    Krishna Myneni <krishna.myneni@ccreweb.org> wrote:

    Below is preliminary test code for floating point comparisons for
    systems with expected IEEE 754 behavior.

    Relevant floating point exceptions should be masked.

    Please let me know if you find any errors in the tests.

    The tests pass on recent kForth-32/64 development versions (v2.8.0 and
    v0.8.0, respectively):
    TESTING F=
    TESTING F<>
    TESTING F<
    TESTING F>
    TESTING F<=
    TESTING F>=
    TESTING F0=
    TESTING F0<
    TESTING F0>

    The auxiliary code, ieee-754.4th, which defines special values is also
    attached below.

    --
    Krishna Myneni

    2 attachments:

    ieee-comparisons-test.4th
    ieee-754.4th

    \ ===== begin ieee-comparisons-test.4th =====
    \ ieee-comparisons-test.4th
    \
    \ Comparison of IEEE 754 special values
    \ Floating point exceptions should be masked.
    \
    \ include ans-words.4th (needed for kForth only)
    include ttester.4th
    include ieee-754.4th


    Tested it on lxf64. No errors reported!

    I needed to define +NAN and +INF, I had them as NAN and INF.
    But I print them out as +INF etc! It makes more sense with the +

    I did not include the ieee-754.4th as that did not add anything.

    on lxf there is a problem with f<> and NANs. I need to correct f<>
    ...

    Good to hear.

    I included ieee-754.4th for Forth systems which did not have +/-INF and +/-NAN defined. It also provides the extremely useful words FINFINITE?
    and FNAN? to check for infinities and NANs resulting from calculations,
    as well as FSUBNORMAL? when the results are represented with less
    precision than standard double precision. These words are all part of
    David Williams' IEEE proposal.

    The rationale for the signed NAN is unclear to me, but I think David had
    a good reason to include it in his IEEE proposal. It may be useful in
    some numerical computation cases. I will look into this further.

    The sign is merely an artefact of the preceding calculation and has no
    inherent significance. Even in applications that use NaN-boxing, the
    possible range of values does not include the bit position of the sign.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Mon May 4 17:20:39 2026
    From Newsgroup: comp.lang.forth

    On 5/4/26 14:53, minforth wrote:
    Am 04.05.2026 um 14:29 schrieb Krishna Myneni:
    On 5/4/26 02:43, peter wrote:
    On Sun, 3 May 2026 22:00:56 -0500
    Krishna Myneni <krishna.myneni@ccreweb.org> wrote:

    Below is preliminary test code for floating point comparisons for
    systems with expected IEEE 754 behavior.

    Relevant floating point exceptions should be masked.

    Please let me know if you find any errors in the tests.

    ...

    I included ieee-754.4th for Forth systems which did not have +/-INF
    and +/-NAN defined. It also provides the extremely useful words
    FINFINITE? and FNAN? to check for infinities and NANs resulting from
    calculations, as well as FSUBNORMAL? when the results are represented
    with less precision than standard double precision. These words are
    all part of David Williams' IEEE proposal.

    The rationale for the signed NAN is unclear to me, but I think David
    had a good reason to include it in his IEEE proposal. It may be useful
    in some numerical computation cases. I will look into this further.

    The sign is merely an artefact of the preceding calculation and has no inherent significance. Even in applications that use NaN-boxing, the
    possible range of values does not include the bit position of the sign.


    The Wikipedia page on IEEE 754 (link below) discusses a type of
    comparison called "total-ordering predicate" in which,

    "NaN is treated as if it had a larger absolute value than Infinity (or
    any other floating-point numbers). (−NaN < −Infinity; +Infinity < +NaN.)"

    Ordinary comparisons with +/-NAN are considered unordered. I don't know
    of any computational uses for this sort of comparison, but I expect it wouldn't be discussed if it did not have some uses.

    --
    Krishna



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Tue May 5 11:32:43 2026
    From Newsgroup: comp.lang.forth

    On 5/05/2026 5:53 am, minforth wrote:
    Am 04.05.2026 um 14:29 schrieb Krishna Myneni:
    ...
    I included ieee-754.4th for Forth systems which did not have +/-INF and +/-NAN defined. It also provides the extremely useful words FINFINITE? and FNAN? to check for infinities and NANs resulting from calculations, as well as FSUBNORMAL? when the results are represented with less precision than standard double precision. These words are all part of David Williams' IEEE proposal.

    The rationale for the signed NAN is unclear to me, but I think David had a good reason to include it in his IEEE proposal. It may be useful in some numerical computation cases. I will look into this further.

    The sign is merely an artefact of the preceding calculation and has no inherent significance. Even in applications that use NaN-boxing, the
    possible range of values does not include the bit position of the sign.

    When creating constants that represent NAN the sign bit will necessarily
    be there. That's enough to include it in the identifier IMO. Similarly
    when displaying fp datum that happen to be NAN. I would rather see more information than less. When I'm told something occurred "last year" it
    only begs the question "exactly when?".




    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Krishna Myneni@krishna.myneni@ccreweb.org to comp.lang.forth on Wed May 6 08:23:47 2026
    From Newsgroup: comp.lang.forth

    On 5/3/26 22:00, Krishna Myneni wrote:
    Below is preliminary test code for floating point comparisons for
    systems with expected IEEE 754 behavior.

    Relevant floating point exceptions should be masked.

    Please let me know if you find any errors in the tests.

    The tests pass on recent kForth-32/64 development versions (v2.8.0 and v0.8.0, respectively):
    TESTING F=
    TESTING F<>
    TESTING F<
    TESTING F>
    TESTING F<=
    TESTING F>=
    TESTING F0=
    TESTING F0<
    TESTING F0>

    ...

    My test code ieee-comparisons-test.4th for testing the following
    comparisons with IEEE special values is now part of the system test code
    for kForth-32/64. The comparisons tested are

    F= F<> F< F> F<= F>= F0= F0< F0>

    It does not contain tests for the comparison word F~ for which there is already existing system test code called ieee-fprox-test.4th in the
    kForth packages. The test code for F~ was written by David Williams.

    The tests performed by ieee-comparisons-test.4th and ieee-fprox-test.4th
    rely on the definition of the following floating point constants:

    +INF -INF +NAN -NAN


    David Williams' last draft of his IEEE fp proposal, v0.5.5,

    "Proposal for an optional IEEE 754, Binary Floating-Point Word Set,"

    contained in the text file, dated 12 Aug 2020,

    ieee-fp-0.5.5.txt

    (the internal date in the document is given as 31 Aug 2009, but I know
    he was working on it in 2020 so I believe the file date over the date contained in the document). This file proposes to standardize the
    following comparison words, Section 8.3, "Comparison",

    F< F= F> F>= F0< F0= F0<= F0>= F~

    The proposal does not standardize the name of the inequality comparison
    F<> -- indeed the proposal nowhere references F<> though it is common
    use in Forth systems.

    The proposal standardizes the following floating point constants,
    Section 7.1, "Constants",

    +INF -INF +NAN -NAN

    Another set of words which David's proposal standardizes, and are
    relevant to recent discussions, are the floating-point value
    classification words, Section 8.4, "Classification",

    FINITE?
    FNORMAL?
    FSUBNORMAL?
    FINFINITE?
    FNAN?

    corresponding to functions provided by C99.

    In kForth, the proposed standard constants and the classification words
    are provided by ieee-754.4th.

    I downloaded an archive of David's personal webpages at umich.edu, so I
    have access to these files. They appear to have been taken down now, and
    I will make his draft proposal, reference implementation, and test code
    for the reference implementation available on ccreweb.org (link to be
    posted in a separate thread).


    Status of Forth-20xx

    The current downloadable Forth-2012 standard document from

    https://forth-standard.org

    dated 10 Nov 2014, specifies only the following floating point comparisons:

    12.6.1.1440 F0<
    12.6.1.1450 F0=
    12.6.1.1460 F<
    12.6.2.1640 F~

    much sparser than what I imagined to be part of the standard, though the
    other comparisons may be defined in terms of these.

    --
    Krishna Myneni
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From marcel hendrix@mhx@iae.nl to comp.lang.forth on Fri Jul 3 15:11:44 2026
    From Newsgroup: comp.lang.forth

    On 5/4/2026 2:29 PM, Krishna Myneni wrote:
    [..]> The rationale for the signed NAN is unclear to me, but I think
    David had
    a good reason to include it in his IEEE proposal. It may be useful in
    some numerical computation cases. I will look into this further.
    This Fortran program shows an (artifical) use.
    Sorry for not properly rewrapping.

    -marcel

    ANEW -testnans

    DOC
    (*
    comp.lang.fortran #73510 (1 more)
    Reply-To: "Matthew C Roberts" <iday_amspayDELETETHESELETTERS@hotmail.com>
    From: "Matthew C Roberts" <therobertsDELETETHESELETTERS@sprintmail.com>
    Subject: IEEE compliance of NaNs
    Lines: 98
    Date: Fri Sep 15 20:11:53 CEST 2000

    O those more learned than I,
    I had a meeting with a professor today who knows WAY more about most things
    than I. I had some questions about some Fortran packages he'd written.
    During the discussion, he asked what compiler I used & I said CVF. He
    bemoaned it, as well as, in his words, every other F90/95 compiler he'd
    tested (which he admitted was far from conclusive) for not being IEEE
    compliant. He uses g77 and said that he's found other FORTRAN77 compilers
    that are acceptable, but not '90/95. I'm not taking sides on this, 'cause I
    don't know enough to, but I wanted to solicit opinions. He has written a
    little bit of code that demonstrates this... here it is (only very slightly
    modified to fit in my DOS window :) ) FWIW, my platform (NT4 SP5, CVF6.1a)
    fails the 6th & 12th tests.

    Thoughts?


    --
    Matthew C Roberts
    Graduate Student
    Department of Economics
    NC State University

    iday_amspay@DIESPAMDIEhotmail.com
    % TO REPLY TO THIS MESSAGE
    % REMOVE ALL CAPITAL LETTERS
    % FROM THE EMAIL ADDRESS

    implicit none

    real*8 x,y,z,v,r,s,ignore

    v = 1.d0
    y = 0.d0

    r = 1.d0
    s = 1.d0

    z = DSQRT(r) - DSQRT(s)
    z = DABS(z)

    x=y/z

    write(*,*) ' '

    write(*,'(a)') 'COMPUTED VALUE CORRECT VALUE'

    write(*,*) ' '
    write(*,'(a,f9.6,a)') ' x = ', x, ' x = NaN'
    write(*,'(a,f9.6,a)') ' v = ', v, ' v = 1.00000'
    write(*,*) ' '

    write(*,*) ' (x.eq.v) =', (x.eq.v), ' (x.eq.v) = F'
    write(*,*) ' (x.lt.v) =', (x.lt.v), ' (x.lt.v) = F'
    write(*,*) ' (x.le.v) =', (x.le.v), ' (x.le.v) = F'
    write(*,*) ' (x.gt.v) =', (x.gt.v), ' (x.gt.v) = F'
    write(*,*) ' (x.ge.v) =', (x.ge.v), ' (x.ge.v) = F'
    write(*,*) ' (x.ne.v) =', (x.ne.v), ' (x.ne.v) = T'
    write(*,*) ' '
    write(*,*) ' (x.eq.x) =', (x.eq.x), ' (x.eq.x) = F'
    write(*,*) ' (x.lt.x) =', (x.lt.x), ' (x.lt.x) = F'
    write(*,*) ' (x.le.x) =', (x.le.x), ' (x.le.x) = F'
    write(*,*) ' (x.gt.x) =', (x.gt.x), ' (x.gt.x) = F'
    write(*,*) ' (x.ge.x) =', (x.ge.x), ' (x.ge.x) = F'
    write(*,*) ' (x.ne.x) =', (x.ne.x), ' (x.ne.x) = T'

    write(*,*) ' '
    write(*,*) 'Press ENTER to continue tests'
    read(*,'(a)') ignore

    x=-x

    write(*,*) ' '
    write(*,'(a,f9.6,a)') ' x = ', x, ' x = -NaN'
    write(*,'(a,f9.6,a)') ' v = ', v, ' v = 1.00000'
    write(*,*) ' '

    write(*,*) ' (x.eq.v) =', (x.eq.v), ' (x.eq.v) = F'
    write(*,*) ' (x.lt.v) =', (x.lt.v), ' (x.lt.v) = F'
    write(*,*) ' (x.le.v) =', (x.le.v), ' (x.le.v) = F'
    write(*,*) ' (x.gt.v) =', (x.gt.v), ' (x.gt.v) = F'
    write(*,*) ' (x.ge.v) =', (x.ge.v), ' (x.ge.v) = F'
    write(*,*) ' (x.ne.v) =', (x.ne.v), ' (x.ne.v) = T'
    write(*,*) ' '
    write(*,*) ' (x.eq.x) =', (x.eq.x), ' (x.eq.x) = F'
    write(*,*) ' (x.lt.x) =', (x.lt.x), ' (x.lt.x) = F'
    write(*,*) ' (x.le.x) =', (x.le.x), ' (x.le.x) = F'
    write(*,*) ' (x.gt.x) =', (x.gt.x), ' (x.gt.x) = F'
    write(*,*) ' (x.ge.x) =', (x.ge.x), ' (x.ge.x) = F'
    write(*,*) ' (x.ne.x) =', (x.ne.x), ' (x.ne.x) = T'

    write(*,*) ' '

    end
    *)
    ENDDOC

    : FVALUES 0 DO 0e FVALUE LOOP ;
    : .BOOL ( flag -- ) IF ." TRUE " ELSE ." FALSE" ENDIF ;

    6 FVALUES x y z v r s

    : TEST-NANS ( -- )
    1e TO v
    0e TO y

    1e TO r
    1e TO s

    6 SET-PRECISION

    0e TO x

    CR ." COMPUTED VALUE CORRECT VALUE" CR
    CR ." x = " x 9 F.R ." x = 0.000000"
    CR ." v = " v 9 F.R ." v = 1.000000"
    CR
    CR ." x F0= = " x F0= .BOOL ." x F0= = TRUE "
    CR ." x F0< = " x F0< .BOOL ." x F0< = FALSE"
    CR ." x F0<= = " x F0<= .BOOL ." x F0<= = TRUE "
    CR ." x F0> = " x F0> .BOOL ." x F0> = FALSE"
    CR ." x F0>= = " x F0>= .BOOL ." x F0>= = TRUE "
    CR ." x F0<> = " x F0<> .BOOL ." x F0<> = FALSE"
    CR
    CR ." v F0= = " v F0= .BOOL ." v F0= = FALSE"
    CR ." v F0< = " v F0< .BOOL ." v F0< = FALSE"
    CR ." v F0<= = " v F0<= .BOOL ." v F0<= = FALSE"
    CR ." v F0> = " v F0> .BOOL ." v F0> = TRUE "
    CR ." v F0>= = " v F0>= .BOOL ." v F0>= = TRUE "
    CR ." v F0<> = " v F0<> .BOOL ." v F0<> = TRUE "
    CR
    CR ." Press ENTER to continue tests" KEY DROP

    7e TO x

    CR ." COMPUTED VALUE CORRECT VALUE" CR
    CR ." x = " x 9 F.R ." x = 7.000000"
    CR ." v = " v 9 F.R ." v = 1.000000"
    CR
    CR ." x v F= = " x v F= .BOOL ." x v F= = FALSE"
    CR ." x v F< = " x v F< .BOOL ." x v F< = FALSE"
    CR ." x v F<= = " x v F<= .BOOL ." x v F<= = FALSE"
    CR ." x v F> = " x v F> .BOOL ." x v F> = TRUE "
    CR ." x v F>= = " x v F>= .BOOL ." x v F>= = TRUE "
    CR ." x v F<> = " x v F<> .BOOL ." x v F<> = TRUE "
    CR
    CR ." x x F= = " x x F= .BOOL ." x x F= = TRUE "
    CR ." x x F< = " x x F< .BOOL ." x x F< = FALSE"
    CR ." x x F<= = " x x F<= .BOOL ." x x F<= = TRUE "
    CR ." x x F> = " x x F> .BOOL ." x x F> = FALSE"
    CR ." x x F>= = " x x F>= .BOOL ." x x F>= = TRUE "
    CR ." x x F<> = " x x F<> .BOOL ." x x F<> = FALSE"
    CR
    CR ." Press ENTER to continue tests" KEY DROP

    r FSQRT s FSQRT F- TO z ( +-0 )
    z FABS TO z ( 0 )

    y z F/ TO x ( 0 / 0 )

    CR ." COMPUTED VALUE CORRECT VALUE" CR
    CR ." x = " x 9 F.R ." x = NaN"
    CR ." v = " v 9 F.R ." v = 1.000000"
    CR
    CR ." x v F= = " x v F= .BOOL ." x v F= = FALSE"
    CR ." x v F< = " x v F< .BOOL ." x v F< = FALSE"
    CR ." x v F<= = " x v F<= .BOOL ." x v F<= = FALSE"
    CR ." x v F> = " x v F> .BOOL ." x v F> = FALSE"
    CR ." x v F>= = " x v F>= .BOOL ." x v F>= = FALSE"
    CR ." x v F<> = " x v F<> .BOOL ." x v F<> = TRUE "
    CR
    CR ." x x F= = " x x F= .BOOL ." x x F= = FALSE"
    CR ." x x F< = " x x F< .BOOL ." x x F< = FALSE"
    CR ." x x F<= = " x x F<= .BOOL ." x x F<= = FALSE"
    CR ." x x F> = " x x F> .BOOL ." x x F> = FALSE"
    CR ." x x F>= = " x x F>= .BOOL ." x x F>= = FALSE"
    CR ." x x F<> = " x x F<> .BOOL ." x x F<> = TRUE "
    CR
    CR ." Press ENTER to continue tests" KEY DROP

    x FNEGATE TO x

    CR ." x = " x 9 F.R ." x = -NaN"
    CR ." v = " v 9 F.R ." v = 1.000000"
    CR
    CR ." x v F= = " x v F= .BOOL ." x v F= = FALSE"
    CR ." x v F< = " x v F< .BOOL ." x v F< = FALSE"
    CR ." x v F<= = " x v F<= .BOOL ." x v F<= = FALSE"
    CR ." x v F> = " x v F> .BOOL ." x v F> = FALSE"
    CR ." x v F>= = " x v F>= .BOOL ." x v F>= = FALSE"
    CR ." x v F<> = " x v F<> .BOOL ." x v F<> = TRUE "
    CR
    CR ." x x F= = " x x F= .BOOL ." x x F= = FALSE"
    CR ." x x F< = " x x F< .BOOL ." x x F< = FALSE"
    CR ." x x F<= = " x x F<= .BOOL ." x x F<= = FALSE"
    CR ." x x F> = " x x F> .BOOL ." x x F> = FALSE"
    CR ." x x F>= = " x x F>= .BOOL ." x x F>= = FALSE"
    CR ." x x F<> = " x x F<> .BOOL ." x x F<> = TRUE "
    CR
    CR ." Press ENTER to continue tests" KEY DROP

    1e 0e F/ TO x

    CR ." x = " x 9 F.R ." x = +Inf"
    CR ." v = " v 9 F.R ." v = 1.000000"
    CR
    CR ." x v F= = " x v F= .BOOL ." x v F= = FALSE"
    CR ." x v F< = " x v F< .BOOL ." x v F< = FALSE"
    CR ." x v F<= = " x v F<= .BOOL ." x v F<= = FALSE"
    CR ." x v F> = " x v F> .BOOL ." x v F> = TRUE "
    CR ." x v F>= = " x v F>= .BOOL ." x v F>= = TRUE "
    CR ." x v F<> = " x v F<> .BOOL ." x v F<> = TRUE "
    CR
    CR ." x x F= = " x x F= .BOOL ." x x F= = TRUE "
    CR ." x x F< = " x x F< .BOOL ." x x F< = FALSE"
    CR ." x x F<= = " x x F<= .BOOL ." x x F<= = TRUE "
    CR ." x x F> = " x x F> .BOOL ." x x F> = FALSE"
    CR ." x x F>= = " x x F>= .BOOL ." x x F>= = TRUE "
    CR ." x x F<> = " x x F<> .BOOL ." x x F<> = FALSE"
    CR
    CR ." Press ENTER to continue tests" KEY DROP

    -1e 0e F/ TO x

    CR ." x = " x 9 F.R ." x = -Inf"
    CR ." v = " v 9 F.R ." v = 1.000000"
    CR
    CR ." x v F= = " x v F= .BOOL ." x v F= = FALSE"
    CR ." x v F< = " x v F< .BOOL ." x v F< = TRUE "
    CR ." x v F<= = " x v F<= .BOOL ." x v F<= = TRUE "
    CR ." x v F> = " x v F> .BOOL ." x v F> = FALSE"
    CR ." x v F>= = " x v F>= .BOOL ." x v F>= = FALSE"
    CR ." x v F<> = " x v F<> .BOOL ." x v F<> = TRUE "
    CR
    CR ." x x F= = " x x F= .BOOL ." x x F= = TRUE "
    CR ." x x F< = " x x F< .BOOL ." x x F< = FALSE"
    CR ." x x F<= = " x x F<= .BOOL ." x x F<= = TRUE "
    CR ." x x F> = " x x F> .BOOL ." x x F> = FALSE"
    CR ." x x F>= = " x x F>= .BOOL ." x x F>= = TRUE "
    CR ." x x F<> = " x x F<> .BOOL ." x x F<> = FALSE" ;

    CR .( Try: TEST-NANS )

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Sat Jul 4 00:50:09 2026
    From Newsgroup: comp.lang.forth

    On 3/07/2026 11:11 pm, marcel hendrix wrote:
    On 5/4/2026 2:29 PM, Krishna Myneni wrote:
    [..]> The rationale for the signed NAN is unclear to me, but I think David had
    a good reason to include it in his IEEE proposal. It may be useful in some numerical computation cases. I will look into this further.
    This Fortran program shows an (artifical) use.
    Sorry for not properly rewrapping.

    -marcel

    So things such as this can't be expected to work with NANs ;-)

    : F>= F< NOT ;

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

    dxf <dxforth@gmail.com> writes:
    So things such as this can't be expected to work with NANs ;-)

    : F>= F< NOT ;

    It certainly behaves differently from the F>= in Gforth:

    Gforth's F>=:

    \ the usual comparisons with NaNs always yield 0 (unordered), except for F<> NaN 0e f>= . \ 0 ok
    0e NaN f>= . \ 0 ok

    After

    : f>= f< 0= ;

    NaN 0e f>= . \ -1 ok
    0e NaN f>= . \ -1 ok

    There is another set of comparison operators with somewhat unusual
    names (that I forgot) that yield true on comparison with NaNs or false
    in the case of the one corresponding to F<>. You can synthesize them
    in Gforth using F< 0=, F<= 0=, ...

    One thing that is also relevant is that when you do something like

    ( r1 r2 ) f< if \ both operands are numbers and r1<r2
    code1
    else \ r1>=r2 or at least one of them is a NaN
    code2
    then

    you may actually not be prepared for all the possible variants in the
    else case, and may prefer to write that instead:

    ( r1 r2 ) fover fover f< if
    fdrop fdrop code1
    else f>= if
    code2
    else \ r1 or r2 (or both) is a NaN
    code3
    then then

    If such things happen regularly, a multi-branch FP-comparison-and-deal-with-different cases construct may be the way
    to go.

    - 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 Sat Jul 4 12:34:28 2026
    From Newsgroup: comp.lang.forth

    On 4/07/2026 1:39 am, Anton Ertl wrote:
    dxf <dxforth@gmail.com> writes:
    So things such as this can't be expected to work with NANs ;-)

    : F>= F< NOT ;

    It certainly behaves differently from the F>= in Gforth:

    Gforth's F>=:

    \ the usual comparisons with NaNs always yield 0 (unordered), except for F<> NaN 0e f>= . \ 0 ok
    0e NaN f>= . \ 0 ok

    After

    : f>= f< 0= ;

    NaN 0e f>= . \ -1 ok
    0e NaN f>= . \ -1 ok

    There is another set of comparison operators with somewhat unusual
    names (that I forgot) that yield true on comparison with NaNs or false
    in the case of the one corresponding to F<>. You can synthesize them
    in Gforth using F< 0=, F<= 0=, ...

    One thing that is also relevant is that when you do something like

    ( r1 r2 ) f< if \ both operands are numbers and r1<r2
    code1
    else \ r1>=r2 or at least one of them is a NaN
    code2
    then

    you may actually not be prepared for all the possible variants in the
    else case, and may prefer to write that instead:

    ( r1 r2 ) fover fover f< if
    fdrop fdrop code1
    else f>= if
    code2
    else \ r1 or r2 (or both) is a NaN
    code3
    then then

    If such things happen regularly, a multi-branch FP-comparison-and-deal-with-different cases construct may be the way
    to go.

    AFAICS the presence of a NAN usually means something has gone awry in which case it may be neither here nor there what branch an application takes.
    OTOH if an IEEE implementation is going to provide extended comparisons,
    it ought at least deliver the results expected. Thanks to Marcel's test
    I discovered mine didn't.

    For completeness the test should do F0<= F0>= F0<> with NANs. Lastly, the computed NAN in the test (0/0) assumes an unsigned NAN is returned ... which the test then proceeds to negate. While users (myself included) have come
    to expect to see NANs represented with a sign which can be negated, AFAIK
    it's not part of the IEEE canon.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Sat Jul 4 05:08:59 2026
    From Newsgroup: comp.lang.forth

    dxf <dxforth@gmail.com> writes:
    AFAICS the presence of a NAN usually means something has gone awry in which >case it may be neither here nor there what branch an application takes.

    For an iterative algorithm that stops based on a floating-point
    comparison, like a typical Newton-Raphson implementation, or a
    quadrature (numerical integration) algorithm, deciding to stay in the
    loop when a NaN is involved will typically lead to an infinite loop.
    Exiting and reporting the NaN is probably preferable.

    For an operation like the sign function, if you do not think about
    NaNs, then, depending on you you implement it, NaN FSGN will result in
    -1, 0, or 1, while the caller probably want the result to be NaN.

    Similar, for functions like FMIN or FMAX, you want to think about what
    to do about NaNs.

    Basically, any time you use an FP comparison, it's a good idea to
    think about NaNs. Fortunately, FP comparisons are relatively rare.

    - 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 peter@peter.noreply@tin.it to comp.lang.forth on Sat Jul 4 10:21:04 2026
    From Newsgroup: comp.lang.forth

    On Fri, 3 Jul 2026 15:11:44 +0200
    marcel hendrix <mhx@iae.nl> wrote:

    On 5/4/2026 2:29 PM, Krishna Myneni wrote:
    [..]> The rationale for the signed NAN is unclear to me, but I think
    David had
    a good reason to include it in his IEEE proposal. It may be useful in
    some numerical computation cases. I will look into this further.
    This Fortran program shows an (artifical) use.
    Sorry for not properly rewrapping.

    -marcel


    Welcome back!

    Defining the missing comparisons as

    : F0<= FDUP F0= F0< OR ;
    : F0>= FDUP F0= F0> OR ;
    : F0<> FDUP F0> F0< OR ;

    made LXF64 pass all tests!

    BR
    Peter

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Sat Jul 4 08:55:09 2026
    From Newsgroup: comp.lang.forth

    anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
    For an operation like the sign function, if you do not think about
    NaNs, then, depending on you you implement it, NaN FSGN will result in
    -1, 0, or 1, while the caller probably want the result to be NaN.

    The following satisfies the requirements above:

    : fsgn ( r1 -- r2 )
    case
    fdup f0< ?of fdrop -1e endof
    fdup f0> ?of fdrop 1e endof
    0 endcase ;

    -5e fsgn f. \ -1. ok
    3e fsgn f. \ 1. ok
    0e fsgn f. \ 0. ok
    NaN fsgn f. \ NaN ok

    - 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 anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Sat Jul 4 09:10:33 2026
    From Newsgroup: comp.lang.forth

    peter <peter.noreply@tin.it> writes:
    Defining the missing comparisons as

    : F0<= FDUP F0= F0< OR ;
    : F0>= FDUP F0= F0> OR ;
    : F0<> FDUP F0> F0< OR ;

    made LXF64 pass all tests!

    I don't find any tests for F0<= F0>= F0<> in
    <10t9259$3c72d$1@dont-email.me>.

    Anyway, the definitions of F0<= and F0>= look ok to me, but NaN F0<>
    should produce true (at least if you want consistency with F<>, which
    is tested), but the definition above produces false.

    - 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 marcel hendrix@mhx@iae.nl to comp.lang.forth on Sat Jul 4 11:43:44 2026
    From Newsgroup: comp.lang.forth

    On 7/4/2026 10:55 AM, Anton Ertl wrote:
    anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
    For an operation like the sign function, if you do not think about
    NaNs, then, depending on you you implement it, NaN FSGN will result in
    -1, 0, or 1, while the caller probably want the result to be NaN.

    The following satisfies the requirements above:

    : fsgn ( r1 -- r2 )
    case
    fdup f0< ?of fdrop -1e endof
    fdup f0> ?of fdrop 1e endof
    0 endcase ;

    -5e fsgn f. \ -1. ok
    3e fsgn f. \ 1. ok
    0e fsgn f. \ 0. ok
    NaN fsgn f. \ NaN ok

    - anton

    David Williams' idea/proposal:

    FORTH> words: FSIGN
    FSIGNBIT FSIGNALING?
    ok
    FORTH> +NAN FSIGNBIT ok
    [1]FORTH> . 0 ok
    FORTH> -NAN FSIGNBIT . -1 ok
    FORTH>

    -marcel
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Sat Jul 4 10:52:45 2026
    From Newsgroup: comp.lang.forth

    marcel hendrix <mhx@iae.nl> writes:
    On 7/4/2026 10:55 AM, Anton Ertl wrote:
    anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
    For an operation like the sign function, if you do not think about
    NaNs, then, depending on you you implement it, NaN FSGN will result in
    -1, 0, or 1, while the caller probably want the result to be NaN.
    ...
    David Williams' idea/proposal:

    FORTH> words: FSIGN
    FSIGNBIT FSIGNALING?
    ok
    FORTH> +NAN FSIGNBIT ok
    [1]FORTH> . 0 ok
    FORTH> -NAN FSIGNBIT . -1 ok

    FSIGNBIT just returns the value of the sign bit and has nothing to do
    with the sign function. In particular,

    1e fsignbit . \ 0 ok
    0e fsignbit . \ 0 ok
    -0e fsignbit . \ -1 ok

    By contrast, my FSGN implementation produces an FP value:

    -5e fsgn f. \ -1. ok
    3e fsgn f. \ 1. ok
    0e fsgn f. \ 0. ok
    NaN fsgn f. \ NaN ok

    and for the values above:

    1e fsgn f. \ 1. ok
    0e fsgn f. \ 0. ok
    -0e fsgn f. \ -0. ok

    - 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 Jul 4 19:52:28 2026
    From Newsgroup: comp.lang.forth

    On 7/3/26 08:11, marcel hendrix wrote:
    On 5/4/2026 2:29 PM, Krishna Myneni wrote:
    [..]> The rationale for the signed NAN is unclear to me, but I think
    David had
    a good reason to include it in his IEEE proposal. It may be useful in
    some numerical computation cases. I will look into this further.
    This Fortran program shows an (artifical) use.
    Sorry for not properly rewrapping.

    -marcel

    ANEW -testnans

    DOC
    (*
        comp.lang.fortran #73510 (1 more)
        Reply-To: "Matthew C Roberts" <iday_amspayDELETETHESELETTERS@hotmail.com>
        From: "Matthew C Roberts" <therobertsDELETETHESELETTERS@sprintmail.com>
        Subject: IEEE compliance of NaNs
        Lines: 98
        Date: Fri Sep 15 20:11:53 CEST 2000

        O those more learned than I,
        I had a meeting with a professor today who knows WAY more about most things
        than I. I had some questions about some Fortran packages he'd written.
        During the discussion, he asked what compiler I used & I said CVF. He
        bemoaned it, as well as, in his words, every other F90/95 compiler he'd
        tested (which he admitted was far from conclusive) for not being IEEE
        compliant. He uses g77 and said that he's found other FORTRAN77 compilers
        that are acceptable, but not '90/95. I'm not taking sides on this, 'cause I
        don't know enough to, but I wanted to solicit opinions. He has written a
        little bit of code that demonstrates this... here it is (only very slightly
        modified to fit in my DOS window :) ) FWIW, my platform (NT4 SP5, CVF6.1a)
        fails the 6th & 12th tests.

        Thoughts?


        --
        Matthew C Roberts
        Graduate Student
        Department of Economics
        NC State University

        iday_amspay@DIESPAMDIEhotmail.com
        % TO REPLY TO THIS MESSAGE
        % REMOVE ALL CAPITAL LETTERS
        % FROM THE EMAIL ADDRESS

              implicit none

              real*8 x,y,z,v,r,s,ignore

              v = 1.d0
              y = 0.d0

              r  = 1.d0
              s  = 1.d0

              z = DSQRT(r) - DSQRT(s)
              z = DABS(z)

              x=y/z

              write(*,*) ' '

              write(*,'(a)') 'COMPUTED VALUE     CORRECT VALUE'

              write(*,*) ' '
              write(*,'(a,f9.6,a)') ' x = ', x, '       x =     NaN'
              write(*,'(a,f9.6,a)') ' v = ', v, '       v = 1.00000'
              write(*,*) ' '

              write(*,*) ' (x.eq.v) =', (x.eq.v), ' (x.eq.v) =  F'
              write(*,*) ' (x.lt.v) =', (x.lt.v), ' (x.lt.v) =  F'
              write(*,*) ' (x.le.v) =', (x.le.v), ' (x.le.v) =  F'
              write(*,*) ' (x.gt.v) =', (x.gt.v), ' (x.gt.v) =  F'
              write(*,*) ' (x.ge.v) =', (x.ge.v), ' (x.ge.v) =  F'
              write(*,*) ' (x.ne.v) =', (x.ne.v), ' (x.ne.v) =  T'
              write(*,*) ' '
              write(*,*) ' (x.eq.x) =', (x.eq.x), ' (x.eq.x) =  F'
              write(*,*) ' (x.lt.x) =', (x.lt.x), ' (x.lt.x) =  F'
              write(*,*) ' (x.le.x) =', (x.le.x), ' (x.le.x) =  F'
              write(*,*) ' (x.gt.x) =', (x.gt.x), ' (x.gt.x) =  F'
              write(*,*) ' (x.ge.x) =', (x.ge.x), ' (x.ge.x) =  F'
              write(*,*) ' (x.ne.x) =', (x.ne.x), ' (x.ne.x) =  T'

         write(*,*) ' '
         write(*,*) 'Press ENTER to continue tests'
         read(*,'(a)') ignore

              x=-x

              write(*,*) ' '
              write(*,'(a,f9.6,a)') ' x = ', x, '       x =    -NaN'
              write(*,'(a,f9.6,a)') ' v = ', v, '       v = 1.00000'
              write(*,*) ' '

              write(*,*) ' (x.eq.v) =', (x.eq.v), ' (x.eq.v) =  F'
              write(*,*) ' (x.lt.v) =', (x.lt.v), ' (x.lt.v) =  F'
              write(*,*) ' (x.le.v) =', (x.le.v), ' (x.le.v) =  F'
              write(*,*) ' (x.gt.v) =', (x.gt.v), ' (x.gt.v) =  F'
              write(*,*) ' (x.ge.v) =', (x.ge.v), ' (x.ge.v) =  F'
              write(*,*) ' (x.ne.v) =', (x.ne.v), ' (x.ne.v) =  T'
              write(*,*) ' '
              write(*,*) ' (x.eq.x) =', (x.eq.x), ' (x.eq.x) =  F'
              write(*,*) ' (x.lt.x) =', (x.lt.x), ' (x.lt.x) =  F'
              write(*,*) ' (x.le.x) =', (x.le.x), ' (x.le.x) =  F'
              write(*,*) ' (x.gt.x) =', (x.gt.x), ' (x.gt.x) =  F'
              write(*,*) ' (x.ge.x) =', (x.ge.x), ' (x.ge.x) =  F'
              write(*,*) ' (x.ne.x) =', (x.ne.x), ' (x.ne.x) =  T'

              write(*,*) ' '

              end
    *)
    ENDDOC

    I compiled and ran the fortran program above to see which tests fail
    under gfortran:

    $ gfortran --version
    GNU Fortran (GCC) 11.5.0 20240719 (Red Hat 11.5.0-14)
    Copyright (C) 2021 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is
    NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
    PURPOSE.

    $ gfortran -o test-nan-comparisons test-nan-comparisons.f

    Here are the results of running it.
    $ ./test-nan-comparisons

    == Begin output ==

    COMPUTED VALUE CORRECT VALUE

    x = NaN x = NaN
    v = 1.000000 v = 1.00000

    (x.eq.v) = F (x.eq.v) = F
    (x.lt.v) = F (x.lt.v) = F
    (x.le.v) = F (x.le.v) = F
    (x.gt.v) = F (x.gt.v) = F
    (x.ge.v) = F (x.ge.v) = F
    (x.ne.v) = T (x.ne.v) = T

    (x.eq.x) = F (x.eq.x) = F
    (x.lt.x) = F (x.lt.x) = F
    (x.le.x) = F (x.le.x) = F
    (x.gt.x) = F (x.gt.x) = F
    (x.ge.x) = F (x.ge.x) = F
    (x.ne.x) = T (x.ne.x) = T

    Press ENTER to continue tests


    x = NaN x = -NaN
    v = 1.000000 v = 1.00000

    (x.eq.v) = F (x.eq.v) = F
    (x.lt.v) = F (x.lt.v) = F
    (x.le.v) = F (x.le.v) = F
    (x.gt.v) = F (x.gt.v) = F
    (x.ge.v) = F (x.ge.v) = F
    (x.ne.v) = T (x.ne.v) = T

    (x.eq.x) = F (x.eq.x) = F
    (x.lt.x) = F (x.lt.x) = F
    (x.le.x) = F (x.le.x) = F
    (x.gt.x) = F (x.gt.x) = F
    (x.ge.x) = F (x.ge.x) = F
    (x.ne.x) = T (x.ne.x) = T

    == End output ==

    So the tests show that *"correct"* and *computed* values for the NAN and
    -NAN comparisons are the same for the version of gfortran used here.

    It is interesting to note that the Fortran program does not print

    x = -NaN

    for the computed column of the second round of tests, even though the
    Fortran program negated the value of x before doing the second round, using

    x = -x

    where x starts out as NaN.

    However, +NaN and -NaN are interchangeable in all of these tests
    according to the *"correct"* value.

    Only the not equal test ( F<> ) will return TRUE for comparison of +NaN
    or -NaN with any other fp value, including itself. All other comparisons should return FALSE.

    It seems like the same effect can be achieved by ignoring the sign bit
    in comparisons of NaN values.

    The fp comparisons test code in the original post covers some of the
    tests in the Fortran program, but any missing ones (the tests comparing against 1.0e0) can be added if there is any value to doing so.

    --
    KM



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Sun Jul 5 05:10:16 2026
    From Newsgroup: comp.lang.forth

    Krishna Myneni <krishna.myneni@ccreweb.org> writes:
    It seems like the same effect can be achieved by ignoring the sign bit
    in comparisons of NaN values.

    Indeed. The sign bit of a NaN has no significance for the arithmetic
    and comparison operations of IEEE-754, only for the signbit and
    copysign operations, which work on bits of the FP value without
    inspecting the FP value any further (e.g., to see if it is a number).

    - 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 Sun Jul 5 13:19:57 2026
    From Newsgroup: comp.lang.forth

    Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
    Krishna Myneni <krishna.myneni@ccreweb.org> writes:
    It seems like the same effect can be achieved by ignoring the sign bit
    in comparisons of NaN values.

    Indeed. The sign bit of a NaN has no significance for the arithmetic
    and comparison operations of IEEE-754, only for the signbit and
    copysign operations, which work on bits of the FP value without
    inspecting the FP value any further (e.g., to see if it is a number).

    I wonder. Is it not more appropriate to raise an exception whenever
    A float is compares to a NAN? "-INF 1E0 F< " makes sense.
    "NAN 1E0 F<" can hide a mistake.
    Is that against the IEEE standard?


    - anton

    --
    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 anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Sun Jul 5 12:15:54 2026
    From Newsgroup: comp.lang.forth

    albert@SPENARNC.XS4ALL.NL writes:
    I wonder. Is it not more appropriate to raise an exception whenever
    A float is compares to a NAN?

    I'll assume that you mean that a Forth exception should be thrown, not
    that an IEEE FP exception should be raised (which, by default, means
    that a sticky flag is set, and the execution continues). I think the
    latter happens anyway, setting the IEEE-754 "Invalid operation" exception (but probably already in the instruction that produced the NaN).

    Yes, given that flags have only two values, and the fact that with
    words like IF or WHILE, only two outcomes are possible, throwing a
    Forth exception would be one way to deal with the situation. I expect
    that it is appropriate in some cases, but less so in others.

    Is that against the IEEE standard?

    The IEEE standard defines comparisons that have a true or false result
    even when one of the operands is a NaN. How we map these operations
    into Forth is our job to decide. E.g., we could have one set of
    compariosn words that throw and another set that do not. But before standardization of such behaviours, I would like to see some data
    about existing practice, in systems and in programs.

    - 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