LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

Limit Variable to Range

Root / Submissions / [.]

12Me21Created:
Code like:
IF X>maximum THEN X=maximum
IF X<minimum THEN X=minimum
Can be written as:

<variable>=MIN(MAX(<variable>, minimum), maximum)

Example:
X=MIN(MAX(X,0),400)
Y=MIN(MAX(Y,0),240)
Limits X and Y to the screen limits. Use this instead of:
IF X<0 THEN X=0
IF X>399 THEN X=399
IF Y<0 THEN Y=0
IF Y>239 THEN Y=239
I mean you should probably just have checks when you modify your variables

You can't use italics in a [code] segment.

Replying to:haloopdy
You can't use italics in a [code] segment.
Fixed.

I thought I was so clever when I "discovered" this, but it turns out that it's pretty well known in other languages too...

Ohhh my goodness I needed this so much in my life, thank you

This seemed interesting, but according to this test I made, your method seems much slower...
code
I%=0
D=MILLISEC
FOR I%=1 TO 1000000
X=MIN(MAX(X,0),400)
Y=MIN(MAX(Y,0),240)
NEXT
?MILLISEC-D;"ms"
I%=0
D=MILLISEC
FOR I%=1 TO 1000000
IF X<0 THEN X=0
IF X>399 THEN X=399
IF Y<0 THEN Y=0
IF Y>239 THEN Y=239
NEXT
?MILLISEC-D;"ms"
On my New 3DS, using this code, the MIN(MAX( part takes about 2520ms, while the regular IF checks take about 2160ms. Did I screw up, or is it really slower?

ddr

Replying to:Sam
This seemed interesting, but according to this test I made, your method seems much slower...
code
I%=0
D=MILLISEC
FOR I%=1 TO 1000000
X=MIN(MAX(X,0),400)
Y=MIN(MAX(Y,0),240)
NEXT
?MILLISEC-D;"ms"
I%=0
D=MILLISEC
FOR I%=1 TO 1000000
IF X<0 THEN X=0
IF X>399 THEN X=399
IF Y<0 THEN Y=0
IF Y>239 THEN Y=239
NEXT
?MILLISEC-D;"ms"
On my New 3DS, using this code, the MIN(MAX( part takes about 2520ms, while the regular IF checks take about 2160ms. Did I screw up, or is it really slower?
4 simple IFs that don't run are obviously faster than 4 function calls and two assignments that always run, but 0.00036ms per iteration is negligible. The snippet is useful for being short and elegant. To speed it up for the average case (which your test doesn't consider) it could be surrounded by a guarding IF...ENDIF.

Replying to:Sam
This seemed interesting, but according to this test I made, your method seems much slower...
code
I%=0
D=MILLISEC
FOR I%=1 TO 1000000
X=MIN(MAX(X,0),400)
Y=MIN(MAX(Y,0),240)
NEXT
?MILLISEC-D;"ms"
I%=0
D=MILLISEC
FOR I%=1 TO 1000000
IF X<0 THEN X=0
IF X>399 THEN X=399
IF Y<0 THEN Y=0
IF Y>239 THEN Y=239
NEXT
?MILLISEC-D;"ms"
On my New 3DS, using this code, the MIN(MAX( part takes about 2520ms, while the regular IF checks take about 2160ms. Did I screw up, or is it really slower?
In your test, none of the IFs actually run because X and Y are always 0. 2 argument MIN/MAX is actually very fast (for a function call), because it's basically just implemented as A>B ? B : A You can also write things like:
X=MIN(MAX(X+100,0),1000)
vs
X=X+100:IF X<0 THEN X=0 ELSEIF X>1000 THEN X=1000