• Tricky flmod example to test implementations.

    From Brad Lucier@21:1/5 to All on Fri May 8 13:57:04 2020
    I've been thinking about implementations of flmod and fldiv, and came up with the example

    (define x (flexpt 2. 100.))
    (define y (+ (flexpt 2. 50.) 1.))
    (display (= y (exact y))) (newline)
    (display (= x (exact x))) (newline)
    (display (modulo (exact x) (exact y))) (newline)
    (display (flmod x y)) (newline)

    which should print

    #t
    #t
    1
    1.

    at least using the language of R6RS:

    These procedures implement number-theoretic integer division and return the results of the corresponding mathematical operations specified in report section 11.7.3

    Straightforward implementations in IEEE 754 double-precision arithmetic can get this wrong, I've found.

    Brad

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bill@21:1/5 to All on Sat May 9 02:53:56 2020
    s7 does this in its gmp version; in the 64-bit ints/double version it gives
    an out-of-range error for (exact (expt 2.0 100.0)). I think the double to
    int truncation starts to skip ints ca 9007199254740991LL. It affects
    many scheme functions.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Brad Lucier@21:1/5 to All on Sat May 9 09:29:19 2020
    If a system has (roughly) 64-bit fixnums, then in the following example all exact integers are fixnums, all flonums are convertible to fixnums, etc.:

    (define x (flexpt 2. 56.))
    (define y (+ (flexpt 2. 28.) 1.))
    (display (= y (exact y))) (newline)
    (display (= x (exact x))) (newline)
    (display (modulo (exact x) (exact y))) (newline)
    (display (flmod x y)) (newline)

    Frederic Hamel showed me the reduced argument size.

    To be honest, I don't see how to compute flmod and fldiv correctly using IEEE 754 arithmetic (especially because they can take non-integer arguments) except by converting arguments to exact, computing the exact equivalents, then converting back to
    inexact. At least then, if (fldiv x y) is a representable flonum integer, it will be computed correctly.

    Brad

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Brad Lucier@21:1/5 to Brad Lucier on Sat May 9 10:58:12 2020
    On Saturday, May 9, 2020 at 12:29:22 PM UTC-4, Brad Lucier wrote:

    To be honest, I don't see how to compute flmod and fldiv correctly using IEEE 754 arithmetic (especially because they can take non-integer arguments) except by converting arguments to exact, computing the exact equivalents, then converting back to
    inexact.

    Perhaps you can do it by setting rounding modes to round down or round up in the appropriate places.

    Brad

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Alex Shinn@21:1/5 to Brad Lucier on Thu Jul 30 23:25:40 2020
    On Sunday, May 10, 2020 at 1:29:22 AM UTC+9, Brad Lucier wrote:
    If a system has (roughly) 64-bit fixnums, then in the following example all exact integers are fixnums, all flonums are convertible to fixnums, etc.:

    (define x (flexpt 2. 56.))
    (define y (+ (flexpt 2. 28.) 1.))
    (display (= y (exact y))) (newline)
    (display (= x (exact x))) (newline)
    (display (modulo (exact x) (exact y))) (newline)
    (display (flmod x y)) (newline)

    Frederic Hamel showed me the reduced argument size.

    To be honest, I don't see how to compute flmod and fldiv correctly using IEEE 754 arithmetic (especially because they can take non-integer arguments) except by converting arguments to exact, computing the exact equivalents, then converting back to
    inexact. At least then, if (fldiv x y) is a representable flonum integer, it will be computed correctly.

    Chibi gets this right on Linux using a trivial wrapper around remquo(3).

    --
    Alex

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