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 > >
