It is simpler if you use the notation [x]_a^b (i.e. with a subscript and a superscript b) to mean x, clipped to the range a to b, and skip writing +/- infinity if you don't intend clipping on one side. Then you get a bunch of obvious identities like [x]^b = min(x, b) = [b]^x (x capped by b is the same as the smaller of x and b which is the same as b capped by x), [x]_a^b = [b]_a^x, and [x]_a^b = [[x]_a]^b. Putting th…
Math.min(Math.max(num, min), max)
111–120 of 291 posts
Re: Math.min(Math.max(num, min), max)
#112Earlier quoted context omitted.
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)
#113Re: Math.min(Math.max(num, min), max)
#114Re: Math.min(Math.max(num, min), max)
#115Re: Math.min(Math.max(num, min), max)
#116[min, num, max].sort()[1]
[min, num, max].sort()[1] I really love this! I’m not sure whether to laugh, cry, or applaud, but I love how it makes me feel all those emotions at the same time.
Re: Math.min(Math.max(num, min), max)
#117Earlier quoted context omitted.
this doesn't work for NaN, e.g {0d, Double.NaN, 1d} returns 1d.
Does NaN have an "order" in the set of reals or integers or whatever? I would have no idea what to expect from `min(NaN, x)` or max same. But is it specified by an IEEE standard or something?
Re: Math.min(Math.max(num, min), max)
#118Earlier quoted context omitted.
this doesn't work for NaN, e.g {0d, Double.NaN, 1d} returns 1d.
Does NaN have an "order" in the set of reals or integers or whatever? I would have no idea what to expect from `min(NaN, x)` or max same. But is it specified by an IEEE standard or something?
NaN is part of IEEE754 but of course it's not a 'real' number (integer numbers don't have NaNs)
Edit: you can consider NaN (and to a degree both infinities) as an exception, once it occurs - it has to be propagated. Any operation involving NaN should be returning NaN, any operation comparing NaN to anything has to return 'false'. That includes "if (NaN == NaN)". boolean isNaN(double d) is effectively "return d != d;"
Re: Math.min(Math.max(num, min), max)
#119Earlier quoted context omitted.
Great. But I have been programming since about 1985.
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.
It's actually the std::min/std::max version that goes to minsd/maxsd in both clang/gcc.
Re: Math.min(Math.max(num, min), max)
#120Very coincidental I see this post almost immediately after writing the same code: new_poll_rate = \ min( max( 1 / messages_per_second, constants.FASTEST_POLL_RATE ), constants.SLOWEST_POLL_RATE ) I agree with the sentiment, I had to re-read this several times to make sure I got it right.