expr %($f1)

Roman Thilenius's icon

i understand and accept that and why expr %($f1) cannot work
but please how else could i write it?

maybe its just too simple for me, but i dont find a working
expression on my own.

-110

ch's icon

Hi Roman,

Is that what you trying to achieve ? :

[ expr $f1-int($f1/$f2)*$f2 ]

charles

Peter Castine's icon

Since fmod() is the standard C math function for floating-point modulo, one might expect [expr fmod($f1, $f2)] to work.

Of course, it doesn't.

One could file a feature request for expr to support fmod() (or, better still, a % float-operator).

In the meantime, there's Ch's suggestion.

And, of course, the % object, which started supporting floats in an early Max 4 release.

Roman Thilenius's icon

thanks Ch, well hopefully you dont think i was just to lazy to
do it myself but yesterday i wasnt able to make it myself.

i have never made a float % abstraction myself (back in OS9
when % did not support floats) because i simply never needed
it to do floats, that is why i did not knew it offhand.

maybe i make one now.

but in this case i need stuff to work inside expr as this
saves patchcords and improves timing.

actually it is suprising that [expr] does not support "fmod"
or "%", which is probably a less excotic function than natural
log (which noone ever uses) isnt it?

well, there will be a reason for it, we discussed the nature
of calling expr´s function earlier.

-110

Peter Castine's icon

Roman Thilenius wrote on Mon, 27 July 2009 21:48which is probably a less excotic function than natural
log (which noone ever uses) isnt it?

Claiming "no one ever uses" any given function is just begging, pleading to be contradicted, isn't it?

Frankly, I use natural log as often as any of the trig/log functions.

But more to the point is the rather idiosyncratic choices made by expr of which functions from the C math library to support and which to ignore. fmod() would definitely be useful.

Ideally, expr should support all the functions in ISO/IEC 9899:1999 that simply return a value. (ie, functions like frexp(double, int *) with a secondary return value as a pointer argument won't fit into the expr paradigm).

Does Cycling 74 need an 'official' bug report to do anything about this?

Roman Thilenius's icon

peter, ch,

i just found out that

[expr $f1 % $f2]

is how it actually works!

thats already the second new thing i learned about expr/if
this week. the whole thing seems to be more inconsistent than
in your most wet dream.

-110

ch's icon

What do you mean Roman?

[expr $f1 % $f2] outputs the same result as [expr $i1 % $i2],
which is not what i expect.
the only difference is that if $f2 is between 0. and 1., then max crashes (the divide by 0 isn't detected).

by the way, a nice thing about expr that is stated in the reference :
"Additional functions can be added by means of external code resources placed in Max's startup folder."
Have you ever tried that?

Charles

Roman Thilenius's icon

Ch wrote on Fri, 31 July 2009 08:49
What do you mean Roman?

you are right, it does not do float.

but the % sign alone was a surprise for me - i mainly asked
for a formula because i thought % would not work at all.

somehow i tend to think that everything which is fully
supported by the object is noted in the helpfile.

(like i said in the other thread the only additional "undocumented"
feature i knew about was comparison operators.)

Quote:
"Additional functions can be added by means of external code resources placed in Max's startup folder."
Have you ever tried that?

Charles

whoa. no!

and i assume i would need to write c classes for that ...

but i dont have time to discuss that now, as i am going to
implement a coffeemachine in my startup folder asap.

-110

.

Aaron Wharton's icon

My apologies (as I fear I've asked about this before) but I'm currently trying to track down the solution for a true looping euclidean modulo for floats in [expr]:

ie. % 5. =
-10. -9. -8. -7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. =
0. 1. 2. 3. 4. 0. 1. 2. 3. 4. 0. 1. 2. 3. 4. 0. 1. 2. 3. 4. 0. 1. 2. 3. 4.

Roman Thilenius's icon


you can not loop at all within the object. but you can do it around it.

Aaron Wharton's icon

So say if I needed to use [vexpr @scalarmode 1], to act on lists, I'd still need to [iter]?

Roman Thilenius's icon


not on lists, but for your euler thing you need the result of the first round for the second calculation, isnt it?

there are many options to perform a "for loop", including counter & gate or using poly~ in serial mode.

really funny to see my own nonsese question above after all the years... and now i am sitting on the other side of the desk. :P

Aaron Wharton's icon

Yeah, right now I'm convinced this is the simplest option:

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

If anyone knows of a more efficient method, I'd love to see it. :D

Jean-Francois Charles's icon

Here is another version, a little convoluted because of the kind of float modulo:

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

Aaron Wharton's icon

@Jean -- ...This is incredible. I believe this is exactly what I was looking for. Thank you. So. Damn. Much.

Ok. Final question. Is there a way of recreating the [round] function -- ie. [round 0.5] -- within [vexpr]?

Thank you so much, again.
- Aaron

Nick Holmes's icon

There is a round function, but as per C, it rounds to the nearest integer, but we can make it work to the nearest 0.5 too;

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

Aaron Wharton's icon

Ah ok, I see. Thanks for the response. :)

Aaron Wharton's icon

Ok, actual last question:

Is there a way to output a value out a second outlet? (Ie. output a value calculated halfway through, as well as output the overall expression out the first outlet as usual?)

I realize you could just break into 2 separate [vexpr] objects, but yeah. :)

Nick Holmes's icon

No, I don't think there is. It would also be nice is we could do this

[vexpr cos($f1), sin($f1)]

and get a tuple of both results at the (single) output, but as you say, it can also be done with two vexpr.

Jean-Francois Charles's icon

Indeed, 2 separate [vexpr] are just great. Use [t l l] if you want a result before the other.

Aaron Wharton's icon

Ok, duly noted. :) -- Thanks, guys.

Ok, another question. (Apologies. I keep encountering unforeseen snags, lol.)

I'm guessing it wouldn't be possible to consolidate the following into a single expression object:

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

Am I correct in thinking that?

Roman Thilenius's icon


sometimes it can be required to delete most of a patch.

kLSDiz's icon

@Aaron yes, you trigger different calculations from two flonums. It's possibile to do all the maths in one (v)expr, but you have to store value from "B" outside of it.

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