keeping numbers in range

Oct 10, 2009 at 7:46pm

keeping numbers in range

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

Cheers
LL

– Pasted Max Patch, click to expand. –
#45805
Oct 10, 2009 at 10:22pm

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.

#165148
Oct 10, 2009 at 10:57pm

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;)

#P window setfont “Sans Serif” 9.;
#P window linecount 1;
#P comment 308 148 100 196617 choose delay;
#P comment 183 39 100 196617 start cycle;
#P comment 98 359 100 196617 delayed index;
#P number 44 322 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 217 227 27 196617 t b i;
#P newex 205 272 27 196617 – 1;
#P number 310 170 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 219 201 100 196617 expr abs(\$f1 – \$f2);
#P number 98 345 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 99 298 133 196617 if \$i1 > 0 then \$f1 else \$f2;
#P newex 195 115 53 196617 t i i i i;
#P newex 98 238 76 196617 expr \$i1 – \$f2;
#N counter;
#X flags 0 0;
#P newobj 98 162 66 196617 counter;
#P newex 99 138 52 196617 metro 50;
#P toggle 106 115 15 0;
#P newex 194 94 43 196617 int 512;
#P newex 168 60 27 196617 t i b;
#P toggle 168 37 15 0;
#P comment 19 347 100 196617 current index;
#P connect 12 0 7 1;
#P connect 12 0 11 1;
#P connect 6 0 15 0;
#P connect 6 0 7 0;
#P connect 6 0 11 0;
#P connect 13 0 9 1;
#P connect 8 1 13 0;
#P connect 11 0 14 0;
#P connect 14 0 13 0;
#P connect 14 1 13 1;
#P connect 9 0 10 0;
#P connect 7 0 9 0;
#P connect 8 0 6 4;
#P connect 3 0 8 0;
#P connect 5 0 6 0;
#P connect 4 0 5 0;
#P connect 1 0 2 0;
#P connect 2 0 4 0;
#P connect 2 1 3 0;
#P window clipboard copycount 19;

#165149
Oct 11, 2009 at 3:53pm

hi,

I think you just need a kind of modulo :

– Pasted Max Patch, click to expand. –

Ch

#165150
Oct 11, 2009 at 5:50pm

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< =0)]

so that you can combine it with the other expr into

[expr \$i1*((\$i1 - \$f2)>0) + \$i3*((\$i1 - \$f2)< =0)]

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<0)))]

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

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<0)))]

-110

#165151
Oct 12, 2009 at 4:34am

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.

#165152

You must be logged in to reply to this topic.