C side tends to align with more modern   ISO/IEC 60559:2020
https://www.iso.org/standard/80985.html  (which mentioned in
https://en.cppreference.com/c/numeric/math/fmax    for example) which
behavior is more likely "option 1"

вс, 2 авг. 2026 г. в 01:56, Peter McGoron via Chicken-users <
[email protected]>:

> This is on the latest master.
>
>       (max +nan.0 1.0 2.0) => +nan.0
>       (max 1.0 +nan.0 2.0) => 2.0
>       (max 1.0 2.0 +nan.0) => 2.0
>
> This looks like these procedures are using `<` and `>` to compare
> numbers, which fails on NaN.
>
> There are two IEEE ways to handle NaNs in max and min:
>
> 1. Ignore them when possible, and only return a NaN when all arguments
> are NaNs. So the above examples would be equivalent to `(max 1.0 2.0)`.
>
> 2. If any input arguments are NaN, then return a NaN. So each example
> above would return NaN.
>
> The R7RS doesn't specify any of these behaviors.
>
> On the implementations I've tested the examples on that didn't have
> inconsistent results, they all returned NaN when any input is a NaN. So
> I recommend the second option because it will cause more portable
> behavior across implementations.
>
> My suggestion is to replace `(if (> h m) h m)` in the definition of
> `max` with `(##max2 h m)`, where for the two options above:
>
> (define (##max2-option1 h m)
>    (cond
>      ((and (nan? h) (nan? m)) h)
>      ((nan? h) m)
>      ((nan? m) m)
>      ((and (eqv? h -0.0) (eqv? m +0.0)) m)
>      ((and (eqv? h +0.0) (eqv? m -0.0)) h)
>      ((< h m) m)
>      (else h)))
>
> (define (##max2-option2 h m)
>    (cond
>      ((nan? h) h)
>      ((nan? m) m)
>      ((and (eqv? h -0.0) (eqv? m +0.0)) m)
>      ((and (eqv? h +0.0) (eqv? m -0.0)) h)
>      ((< h m) m)
>      (else h)))
>
> IEEE 754-2019 mandates that, for the purposes of max and min, +0.0 is
> greater than -0.0. Similar things apply to min.
>
> I would add the following test cases:
>
>       (max +nan.0 1.0 2.0) => 2.0 (option 1) OR +nan.0 (option 2)
>       (max 1.0 +nan.0 2.0) => same
>       (max 1.0 2.0 +nan.0) => same
>       (max +nan.0)         => +nan.0
>       (max +nan.0 +nan.0)  => +nan.0
>       (max -0.0 +0.0)      => +0.0
>       (max +0.0 -0.0)      => +0.0
>
>       (min +nan.0 1.0 2.0) => 1.0 (option 1) OR +nan.0 (option 2)
>       (min 1.0 +nan.0 2.0) => same
>       (min 1.0 2.0 +nan.0) => same
>       (min +nan.0)         => +nan.0
>       (min +nan.0 +nan.0)  => +nan.0
>       (min -0.0 +0.0)      => -0.0
>       (min +0.0 -0.0)      => -0.0
>
> -- Peter McGoron
>
>

Reply via email to