I find that the fact that the functions min and max have the same name as the variables min and max increases cognitive load which makes it harder to think about it. I find the following easier to read : Math.min(Math.max(num, lower_bound), upper_bound)
I prefer "ceiling" and "floor", but yes, agreed.
Math.min(Math.max(num, min), max)
71–80 of 291 posts
Re: Math.min(Math.max(num, min), max)
#72Always good to know the underlying implementation, but for any Ruby readers check out clamp(). It's been available since 2.4. 25.clamp(5, 10) => 10 6.clamp(5, 10) => 6 1.clamp(5, 10) => 5
Re: Math.min(Math.max(num, min), max)
#73Here's clamp in idiomatic Elixir (using multi-clause functions and guards): def clamp(min, _max, n) when n max, do: max def clamp(_min, _max, n), do: n
defmodule Math do
def clamp(num, _min, max) when num > max, do: max
def clamp(num, min, _max) when num Re: Math.min(Math.max(num, min), max)
#74Earlier quoted context omitted.
That doesn't really help. "Max" to enforce a "lower bound" is briefly halting.
I would prefer it if the methods in java.lang.Math had been called "larger" and "smaller", instead of "min" and "max". I sometimes mix up "min" as "take the minimum" rather than "take the larger given this minimum".
Re: Math.min(Math.max(num, min), max)
#75I find that the fact that the functions min and max have the same name as the variables min and max increases cognitive load which makes it harder to think about it. I find the following easier to read : Math.min(Math.max(num, lower_bound), upper_bound)
Arrays.sort( {lower_bound, num, upper_bound} )[1];
Next challenge: teach the optimizer to make that almost as fast as the min/max way ;-)(You can’t reduce it to the min/max call because it also works if you accidentally pass a lower bound that’s larger than the upper bound. Worst-case, the above takes 3 comparisons, unless at least two of the inputs are constants)
Re: Math.min(Math.max(num, min), max)
#76Earlier quoted context omitted.
That doesn't really help. "Max" to enforce a "lower bound" is briefly halting.
I agree. But "min(-, constant_x)" should be thought of as "at most constant_x" and similarly for max. Maybe there's a way to make it more expressive.
I think `at_most(at_least(num, lower_bound), upper_bound)` is much easier to understand instantly than `min(max(...))`.
I'm tempted to make these aliases myself in some of my development actually. I find a pretty big conceptual difference between "I want to find the minimum point in this data", and "I want to restrict the range of this number" that giving them different names will probably help the readability of my code.
(Of course, for `min(max(...))` I usually write a `clamp()` function to hide that for me, but someones I want to only clamp in one direction)
Re: Math.min(Math.max(num, min), max)
#77In languages I use there’s usually no need to write that code. C++/17 has std::clamp() in header. Modern C# has Math.Clamp() since .NET Core 2.0; too bad it’s not available in desktop edition of the runtime. HLSL has clamp() intrinsic function, and a special version saturate() to clamp into [ 0 .. +1 ] interval.
Huh, that’s good to know. It’s also in .net standard 2.1. A shame it wasn’t added to Framework 4.8 (which I guess is what you mean by "desktop edition of the runtime"?)
Re: Math.min(Math.max(num, min), max)
#78Stage 1 ECMAScript proposal to add Math.clamp (among others): https://github.com/rwaldron/proposal-math-extensions But it looks dead: https://github.com/rwaldron/proposal-math-extensions/issues/... As someone mentioned in the thread, nested ternary is easier to interpret: (a > max ? max : (a < min ? min : a))
a > max ? max :
a Re: Math.min(Math.max(num, min), max)
#79Earlier quoted context omitted.
I’ve been programming for living since 2000, but I don’t think that’s relevant. No reason not to use what’s available in standard libraries of whatever language you’re writing. For example, C++ on AMD64 is very likely to compile std::clamp into 2 instructions, minsd and maxsd. I’m not so sure about nested ternaries mentioned elsewhere in the comments.
There are very good reasons to avoid std:: stuff. And if you don't already know that in your soul, I will appear to be a genuine crackpot, and the reasons not to use std::* will still exist.
Re: Math.min(Math.max(num, min), max)
#80Python also doesn't have a built-in clamp function (I think there might be one in numpy), I usually use sorted((floor, x, ceiling))[1] Throw it in a function with some asserts if you're worried about x not being a number and giving you weird results.