Live data from Hacker News

Math.min(Math.max(num, min), max)

twitter.com

101–110 of 291 posts

Re: Math.min(Math.max(num, min), max)

#101
post #49

Earlier quoted context omitted.

This is also nice because it gracefully handles the case where `max < min`.

It's not always graceful to say that 1 is both less than 0 and greater than 2.

Not sure what you mean. If I want to clamp 1 between 2 and 0, the most reasonable answer is 1, which is correctly returned by this code.

Re: Math.min(Math.max(num, min), max)

#103
post #7

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

At the risk of starting a style debate, this may be easier to read if you write it like an if-else: a > max ? max : a

Unless, of course, your language "designer" has no idea why every other language uses right-associative ternary operators.

Re: Math.min(Math.max(num, min), max)

#105

Fun seeing that pretty much everyone else finds that idiom confusing too. Half-serious, over breakfast: (case [(> n min) ( (Side note: Clojure's `>` and ` n min)` into "if n is greater than min" takes some work for me, still, after more than a year.)

What about the [false false] case where min ≥ n ≥ max?

Re: Math.min(Math.max(num, min), max)

#106

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

> in desktop edition of the runtime huh?

MS .NET framework. Unfortunately, for the last couple years it lags behind .NET core. Even 2 years old .NET core 2.1 is better in some regards than the latest desktop version 4.8.

Re: Math.min(Math.max(num, min), max)

#107

Earlier quoted context omitted.

Can you give an example where median([a, min, max]) is not equal to clamp(a, min, max), given max >= min?

If a max, if I'm reading it right.

You can prove that this algorithm works for both of those cases. Assuming min If a If a > max, then the sorted array is [min, max, a]. The median is max, which is a clamped to max.

Re: Math.min(Math.max(num, min), max)

#108

Earlier quoted context omitted.

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 your "at most" language is pretty expressive. You could do that as an alias for `min` and `max` 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 restr…

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

You could make clamp work in only one direction too. clamp(number, None, upper_bound) or the idiomatic equivalent in your language of choice seems pretty readable.

Re: Math.min(Math.max(num, min), max)

#109
post #75
post #28

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)

Easy to remember, but may take some time to grasp: 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)

this doesn't work for NaN, e.g {0d, Double.NaN, 1d} returns 1d.

Re: Math.min(Math.max(num, min), max)

#110

Always 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

I often see [a, b, c].sort[1] which I think is very neat.

I'd say the only way this would be better than min/max solution is that you can't accidentally flip it when writing the code - but IMO both suck at expressing intent, clamp reads unambiguously.
Post reply on HN