Is it possible to make a clamp function shorter than a ternary in JS?

Imagine this short function to clamp a number between 0 and 255:

c = n => n > 0 ? n < 255 ? n : 255 : 0


Is this the shortest possible version of a clamp function with JavaScript (without ES.Next features)?

P.S: Not sure if it's relevant but, the 0 and 255 are not random, the idea is to clamp a number as an 8-bit unsigned integer.

• Hi and welcome to PPCG! Just to be clear, any answer you receive here will not necessarily be a good idea to use in anything except for code golfing. Aside from that, if you care about what version / environment it has to work in you might want to specify it. – FryAmTheEggman Mar 5 at 23:09
• Oh, I'm well aware. I've updated the question a bit. Thank you :) – Ricardo Amaral Mar 5 at 23:12
• I don't know JS, but one way to clamp is to sort [0,n,255] and take the middle element -- might that be shorter? – xnor Mar 5 at 23:26
• @xnor Unfortunately, the JS sort() method uses a lexicographical comparison by default, so that would require an explicit callback. (Something like that.) – Arnauld Mar 5 at 23:30
• @Arnauld Wow, that's pretty silly. But it looks like it would be longer even if the sort was numerical. – xnor Mar 5 at 23:34

20 bytes

For reference, this is the original version without whitespace and without naming the function:

n=>n>0?n<255?n:255:0


Try it online!

19 bytes

We can save a byte by inverting the logic of the ternary tests and using n>>8 to test whether $$\n\$$ is greater than $$\255\$$. Because of the bitwise operation, this will however fail for $$\n\ge 2^{32}\$$.

n=>n<0?0:n>>8?255:n


Try it online!

19 bytes

This one returns $$\false\$$ instead of $$\0\$$ but works for $$\n\ge 2^{32}\$$.

n=>n>255?255:n>0&&n


Try it online!

18 bytes

By combining both versions above, we end up with a function that works for $$\256-2^{32}\le n<2^{32}\$$ and returns $$\false\$$ for $$\n<0\$$.

n=>n>>8?n>0&&255:n


Try it online!

Commented

n =>          // n = input number
n >> 8 ?    // if n is greater than 255 or n is negative:
n > 0 &&  //   return false if n is negative
255       //   or 255 otherwise
:           // else:
n         //   return n unchanged


(This is a fixed revision of the code proposed by @ValueInk in the comments.)

17 bytes

We can go a step further by limiting the valid input range to $$\-2^{24}< n\le 2^{24}\$$:

n=>n>>8?-n>>>24:n


Try it online!

Commented

n =>          // n = input number
n >> 8 ?    // if n is greater than 255 or n is negative:
-n >>> 24 //   non-arithmetic right-shift of -n by 24 positions
:           // else:
n         //   return n unchanged

• Why stop there? If you're extremely liberal with what counts as a 0 (as JavaScript tends to do) you can always go for n=>n>>8?255:n>0&&n for 18 bytes, since false can be coerced to 0 and this will make all negative numbers evaluate to false – Value Ink Mar 5 at 23:39
• @ValueInk If you don't test $n<0$ beforhand, n>>8 will be truthy for any negative input. – Arnauld Mar 5 at 23:41
• Very nice, thank you so much! – Ricardo Amaral Mar 6 at 10:21