• Overflow Test for M*/

    From Krishna Myneni@21:1/5 to All on Wed Jul 10 06:16:01 2024
    Here's a simple check to see what your Forth system does when M*/ is
    given arguments which will overflow a double length result. The standard
    states that this is an ambiguous condition.

    : ipow ( n u -- d ) 1 s>d rot 0 ?DO 2 pick 1 m*/ LOOP rot drop ;

    65 21 ipow d.
    117809547936177440979200839996337890625 ok \ result ok (64-bit system)

    65 22 ipow d.
    Floating point exception (core dumped) \ kForth-64 (since last commit)

    65 raised to the power of 22 will overflow the double number result on a
    64-bit system and crash on kForth-64. Prior to my recent patch it would overflow silently and print an incorrect result.


    In kForth, a SIGFPE handler may be installed as shown in the example sigfpe.4th.

    include sigfpe
    \ ...
    65 22 ipow d.
    Floating point exception
    Line 16: VM Error(-258): Return stack corrupt
    65 22 ipow d.
    ok \ returns to the Forth prompt


    To be clear there is no floating point operation involved in IPOW as
    defined above, but the exception generated for integer division overflow
    for a double length number divided by a single length number generates
    SIGFPE on linux.

    --
    Krishna

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to All on Wed Jul 10 11:55:18 2024
    Good to have a choice. The now standardised big integer
    wrap-around behaviour in Forth can indeed cause difficulties.

    The other way is to use a small bignum library eg libtommath.
    (afaik Python uses fat GMP)

    MicroPython v1.19.1 on 2022-11-05; win32 [GCC 6.3.0] version
    Use Ctrl-D to exit, Ctrl-E for paste mode
    pow(65,21)
    117809547936177440979200839996337890625
    pow(65,22)
    7657620615851533663648054599761962890625


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Krishna Myneni@21:1/5 to minforth on Wed Jul 10 07:31:23 2024
    On 7/10/24 06:55, minforth wrote:
    Good to have a choice. The now standardised big integer
    wrap-around behaviour in Forth can indeed cause difficulties.


    The Forth 2012 standard for M*/ states an ambiguous condition for a
    quotient outside of the range of a double-precision signed number:

    8.6.1.1820

    M*/ ( d1 n1 +n2 – – d2 )
    Multiply d1 by n1 producing the triple-cell intermediate result t.
    Divide t by +n2 givingthe double-cell quotient d2 . An ambiguous
    condition exists if +n2 is zero or negative, or the quotient lies
    outside of the range of a double-precision signed integer.

    --
    Krishna

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to All on Fri Jul 12 19:29:52 2024
    Why n2 has to be positive is beyond me anyhow.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From mhx@21:1/5 to dxf on Sat Jul 13 07:15:34 2024
    On Sat, 13 Jul 2024 2:03:54 +0000, dxf wrote:

    [..]
    How many applications have you written requiring a negative divisor?

    I note that in the 68 occurrences of M*/ inside about 1900 files,
    32 appear as ".. 1 M*/ ..".

    -marcel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to dxf on Sat Jul 13 08:15:26 2024
    On Sat, 13 Jul 2024 2:03:54 +0000, dxf wrote:
    How many applications have you written requiring a negative divisor?

    What a silly question.

    Even in simple Newtonian physics it is not always possible to define
    a reference system that avoids negative values. Let alone in
    electrical networks.

    The "explanation" that +n2 is there to compensate for the performance
    loss of some (old?) CPUs sounds strange in a standard document.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From mhx@21:1/5 to minforth on Sat Jul 13 09:03:40 2024
    On Sat, 13 Jul 2024 8:15:26 +0000, minforth wrote:

    Even in simple Newtonian physics it is not always possible to define
    a reference system that avoids negative values. Let alone in
    electrical networks.

    I have never felt the need to use M*/ when solving electrical
    networks. Maybe when I finally get to Katzenelson.

    -marcel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Krishna Myneni@21:1/5 to mhx on Sat Jul 13 07:18:11 2024
    On 7/13/24 02:15, mhx wrote:
    On Sat, 13 Jul 2024 2:03:54 +0000, dxf wrote:

    [..]
    How many applications have you written requiring a negative divisor?

    I note that in the 68 occurrences of M*/ inside about 1900 files,
    32 appear as ".. 1 M*/ ..".


    The use of 1 M*/ just points to a missing factor of M*/ being omitted
    from the standard. In kForth, we provide the missing factor:

    DS* ( d n -- t )

    where t is a signed triple length product. Therefore, 1 M*/ can be
    replaced by

    DS* drop

    and the division can be avoided.

    If you need an overflow check, it may be a bit more complicated, though.

    --
    Krishna

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)