
On Tue, Aug 2, 2016, at 14:22, Steven D'Aprano wrote:
In any case, clamping is based of < and > comparisons, which are well-specified by IEEE 754 even when NANs are included:
Sure, but what the standard doesn't say is exactly what sequence of comparisons is entailed by a clamp function. def clamp(x, a, b): if x < a: return a else: if x > b: return b else: return x def clamp(x, a, b): if a <= x: if x <= b: return x else: return b else: return a There are, technically, eight possible naive implementations, varying along three axes: - which of a or b is compared first - x < a (or a > x) vs x >= a (or a <= x) - x > b (or b < x) vs x <= b (or b >= x) And then there are implementations that may do more than two comparisons. def clamp(x, a, b): if a <= x <= b: return x elif x < a: return a else: return b All such functions are equivalent if {a, b, x} is a set over which the relational operators define a total ordering, and a <= b. However, this is not the case if NaN is used for any of the arguments.