Live data from Hacker News

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

twitter.com

71–80 of 291 posts

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

#71
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)

I prefer "ceiling" and "floor", but yes, agreed.

I use ceil/floor (and make people use whenever I can) if something is going to happen when something hits the ceiling or drops to the floor. And avoid if it is just for clamping.

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

#73

Here'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)

#74

Earlier 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".

But "min" does take the minimum: `Math.min(1,3) == 1`

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

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

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

#76

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

#77

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.

> Modern C# has Math.Clamp() since .NET Core 2.0; too bad it’s not available in desktop edition of the runtime.

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)

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

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

#79

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

Are you saying a C++ developer shouldn't use the standard library?

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

#80

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

You could use statistics.median (in python 3.6+)
Post reply on HN