Live data from Hacker News

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

twitter.com

171–180 of 291 posts

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

#171

Earlier quoted context omitted.

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.

He's saying that, if you have explicitly defined a max and min such that max The array implementation sidesteps this by not semantically defining a max and min, instead sorting three arbitrary numbers.

In practice “max” and “min” often aren’t conceptually important for a clamp function. It’s more that you want to keep a value within a range, which is defined by two end points in arbitrary order.

If that is the version of clamp you need, the sort based solution reveals something profound and unexpected: it’s not just the two end points of the range that are equivalent, but all three numbers. Keeping value A between B and C is the same as keeping B between A and C or C between A and B. It’s completely arbitrary which pair you consider to be a range.

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

#172
post #164

Earlier quoted context omitted.

FASTEST_POLL_RATE is 1000hz, SLOWEST_POLL_RATE is 10hz. Thus, FASTEST_POLL_RATE is a smaller number on a per-second basis.

Ah, I see - for clarity I'd rename them FASTEST_POLL_RATE -> SHORTEST_POLL_PERIOD or store them in Hz rather than seconds, so everything was 1/ in that little snippet. Thanks for clearing up my confusion :)

Yeah that’s a very good call, I will probably rename these. Thanks for the critique!

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

#175
post #15

[min, num, max].sort()[1]

It's cute but if you used this in an innerloop (like a game, simulation or graphics code where 'clamp' is used often), it'll generate a ton of garbage as well as potential slowdown for no good reason.

This should be completely obvious, but largely irrelevant to the topic at hand. The linked tweet talks about how difficult it is to remember the order of the terms when you implement clamp a certain way; I just wanted to point out that with a different solution, the order surprisingly doesn’t matter at all.

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

#177
post #151
post #147

I think the main hurdle is that we need to read this inside-out, which is something we face regularly trying to read nested function calls. I seriously believe pipe-like operators solve this problem cleanly. In Elixir which does have the pipe `|>` this could be. number = number |> max(lower_bound) |> min(upper_bound) Which IMO is quite elegant.

Note: I don't really know Elixir, all I know is that this works in repl.it

I use Elixir day to day, and I agree, piping is one of the nicest things about it. And your code is the way I would have written it.

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

#178

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.

If you are writing code that is clamping a lot of numbers, the GC churn from building a new array every time might be a problem.

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

#179
post #132

Kotlin provides pretty nice syntax sugar for that: num.coerceIn(min..max) That's it. This human reader finds it considerably more readable. It also has coerceAtLeast and coerceAtMost

Does kotlinc optimize away inline ranges like that, or does this result in a range object being constructed and discarded?

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

#180
post #145
post #109

Earlier quoted context omitted.

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

So I tried a thing in python3. >>> max(float('nan'), 0) nan >>> max(0, float('nan')) 0 Numpy works though >>> np.maximum(float('nan'), 0) nan >>> np.maximum(0, float('nan')) nan Edit: Fixed numpy example.

The functions minNum and maxNum ([IEEE 754-2008, 5.3.1, p19]) take two arguments and return the min and max, respectively. They have the special, distinguished property that “if exactly one argument is NaN, they return the other. If both are NaN they return NaN.”

Source: http://tom7.org/nand/nand.pdf

Edit: As of 2019, the formerly required minNum, maxNum, minNumMag, and maxNumMag in IEEE 754-2008 are now deleted due to their non-associativity. [https://en.wikipedia.org/wiki/IEEE_754#2019]

Post reply on HN