keeping numbers in range

lut lei's icon

Hello list.

I tried to find a solution to this small problem. After doing arithmetic operations on numbers within a chosen range, the result often fall out of range. I'm trying to keep the result in the permitted range by "folding" it. I guess this must be a very fundamental problem which experienced programmers got a very efficent solution for? Or I hope it is, since my solution seems very convoluted.

Sorry if the problem is poorly described, I guess looking at the patch will offer a better description.

I would gratefully welcome any other solution

Max Patch
Copy patch and select New From Clipboard in Max.

Cheers
LL

Roman Thilenius's icon

i cannot look at max5 patches, but there is [abs],
[clip], [split] for a start.

for things like keeping a range after performing [cos] and
things like that, there is no other option than to find the
desired scaling by trying it out; if the range is 0. - 7.
but should bw 0. - 1. [/ 7.] should help.

lut lei's icon

Appreciate your input Roman, so I made a quick max4 port of what I'm doing. I'm not looking for an external or an object to do this, but a mathematical operation simpler than this method with an conditional statement. If such exists;)

Max Patch
Copy patch and select New From Clipboard in Max.

ch's icon

hi,

I think you just need a kind of modulo :

Max Patch
Copy patch and select New From Clipboard in Max.

Ch

Roman Thilenius's icon

well, beside the question how much sense it makes, you
can for sure make that shorter.

instead of the if

[if $i1 > 0 then $f1 else $f2]

you can use an expr

[expr $i1*($i1>0) + $i2*($i1

so that you can combine it with the other expr into

[expr $i1*(($i1 - $f2)>0) + $i3*(($i1 - $f2)

for the rest i dont really see what it is about - you can
probably replace other 6 objects by a single [- ].

the use of modulo also seems a right idea, itonly has that little proboem that 512 will be 0 again.y you can use some
+1 shifting procedure to fix that, or use the following formula
which is taking from [110.loopi]:

[expr ((($i1%$i2) + ($i2)*(($i1%$i2)==0))*($i1>=0)) + ((((($i1%$i2)+$i2) + (-$i2)*((($i1%$i2)+$i2)==0))*($i1

where input 1 would be your counter output (which no longer would have to be limited to 1-512!) and the secondinput is
your 512.

the same for full floating point modulo looks slightly more anal:

[expr ((($f1-int($f1/$f2)*$f2) + ($f2)*(($f1-int($f1/$f2)*$f2)==0))*($f1>=0)) + ((((($f1-int($f1/$f2)*$f2)+$f2) + (-$f2)*((($f1-int($f1/$f2)*$f2)+$f2)==0))*($f1

-110

seejayjames's icon

one kind of hack way to do this would be to get the number result, then use that to [uzi] that many numbers into a [counter] that has the range you want, and counting mode is up/down. So if you want values from 0-100, and a value like 135 should fold back to 65, you'd have

uzi 135
counter 2 0 100 (2 is the counting mode: up/down)
fire!

it'll ping-pong within the range, sort of an auto-modulus, but mirrored instead of restarting. Probably you'll need to add or subtract 1 at some point to deal with "off-by-one" problems, but hey. And if you want floats just scale them at the end, as counter only plays with ints.