modulo object error?

Dec 10, 2010 at 10:05am

modulo object error?

It seems that the modulo object in Max doesn’t work correctly with floats. Maybe I’m missing something, but 0.5 % 0.1 yields 0.1 when it should yield a 0. (It works fine with float up to .5) Similarly, 1. % 0.2 outputs 0.2 when it should also be 0. Right?

Dec 10, 2010 at 10:25am

OK so in trying to figure out a work-around for this, I used a select object to detect when the output is 0.1 and bang a 0. instead. Except this doesn’t work. Can anyone replicate this or have I simply gone mad?

  1. modtest.maxpat
Dec 10, 2010 at 10:50am

0.1 % 0.1? hum, that’s 0, right? If you do a modulo something, you’ll never reach the something value (cause the remainder of something/something is 0).

Dec 10, 2010 at 11:18am

Hi Emmanuel,

Yes that’s right, and that’s the result that I would like to get–0. However, I am getting 0.1 instead. :(

i.e. 0.5 % 0.1 should yield 0.0 because .5/.1=5 (no remainder).

Dec 10, 2010 at 12:01pm

32 bits floating point. There’s several thread which talks about that, but basically sel 0.1 is actually looking for the value 1.000001. 0.5/0.1 is about 0.99998 or something. So that’s why select doesn’t select ;-)

Dec 10, 2010 at 1:31pm

Not sure that I understand how 0.5/0.1 is .99998 (or even .099998) but I’ll take your word for it. Still, that was just a workaround for the modulo problem. It would be nice if the Max modulo object worked consistently (like a standard calculator) so I could use it practically.

Dec 10, 2010 at 1:58pm

Consistently is not always as expected. Probably Emmanuel meant to say that 0.5/0.1 is about 4.99998 or something (and not 5). When you do a forum search, search for “float castine”. These two concepts are eternally connected. In the meantime, you could solve your problem like this:

– Pasted Max Patch, click to expand. –


Dec 10, 2010 at 2:04pm

A ha–I thought I searched the forums pretty well but apparently not. ;)

Thanks to both of you for helping me understand!

Dec 10, 2010 at 2:06pm

I was about to reply and then saw that it would be irrelevant. Thanks for the compliment (I think), Johan!

There is, of course, the tutorial written by another Peter (Elsea). Highly recommended. <>

Dec 10, 2010 at 2:29pm

i tend to trust people like emmanuel, but i dont understand what he says.

why cant you do a modulo for floats? i do that sometimes.

because i am in mac os classic most of the time, i have to use [expr], of course, and
it does not happen too often that i need to do it, but it “works”.
(who cares that math books usually claim the opposite?)

pauls example seems absolutely valid to me:
“i.e. 0.5 % 0.1 should yield 0.0 because .5/.1=5 (no remainder)”

and [expr $f1%$f2] should output 0 when i am not wrong.


Dec 10, 2010 at 3:06pm

> and [expr $f1%$f2] should output 0 when i am not wrong.

PPC might be able to do that; Intel apparently not. It crashes max–the one with rounded corners. (10.6.5 / 5.1.7)

Thread 0 Crashed: Dispatch queue:
0 com.cycling74.MaxMSP 0x00034b94 ex_eval + 2240
1 com.cycling74.MaxMSP 0x000386aa expr_bang(expr*) + 32
2 com.cycling74.MaxMSP 0x000655f0 outlet_float + 776
3 com.cycling74.MaxAPI 0x0327154b outlet_float + 54
4 com.cycling74.number 0x1935ca1f jflonum_mousedragdelta + 342
5 com.cycling74.MaxMSP 0x000bb49b object_method + 901
6 com.cycling74.MaxMSP 0x0010ca73 BoxComponent::mouseDrag(juce::MouseEvent const&) + 439
7 com.cycling74.MaxMSP 0x002f5bac juce::Component::internalMouseDrag(int, int, long long) + 646
8 com.cycling74.MaxMSP 0x0038fc26 juce::ComponentPeer::handleMouseDrag(int, int, long long) + 114
9 com.cycling74.MaxMSP 0x002d2ad2 juce::juce_dispatchNextMessageOnSystemQueue(bool, bool) + 294
10 com.cycling74.MaxMSP 0x002dc87f juce::MessageManager::dispatchNextMessage(bool, bool*, bool) + 79
11 com.cycling74.MaxMSP 0x002dc93e juce::MessageManager::runDispatchLoop() + 42
12 com.cycling74.MaxMSP 0x002db299 juce::JUCEApplication::main(juce::String&, juce::JUCEApplication*) + 605
13 com.cycling74.MaxMSP 0x002db373 juce::JUCEApplication::main(int, char**, juce::JUCEApplication*) + 125
14 com.cycling74.MaxMSP 0x001e4b00 main + 76
15 com.cycling74.MaxMSP 0x0000647a _start + 216
16 com.cycling74.MaxMSP 0x000063a1 start + 41

Dec 10, 2010 at 3:37pm

oh, so there is actually an appearance of an expr which does not work on a platform.

well, i know why i didnt like the rounded conders, they can not even do %.

Dec 10, 2010 at 3:38pm

what about doing the same with ints?

Dec 10, 2010 at 4:26pm

expr can only do integers modulo. This has been the case for ever.

Dec 11, 2010 at 8:04am

i was confused a bit about the situation, you are right, %0.1 wont work.

there are two things which work:

you may input and output floats in an modulo expression, which
wasnt the case the [%] external in max 4, but works with expr.

and of course you can make your own modulo for floats – USING expression.


  1. modulofloat.jpg
Dec 11, 2010 at 8:05am

there is something wrong with my attachment

Dec 11, 2010 at 6:42pm

i.e. 0.5 % 0.1 should yield 0.0 because .5/.1=5 (no remainder)

Sigh, it looks like Castine does have to explain this yet again.

The value 0.1 simply does not exist in binary fractions.

It’s just like trying to express 1/3 with decimal fractions. You can approximate 1/3 as 0.33 or 0.333 or 0.33333333333333333333333 but you can never express 1/3 *exactly*. Not unless you have time to write an infinite number of digits. Most computers have neither infinite amounts of time nor memory.

With binary fractions you can only express any fractional value as the sum of 1/2, 1/4, 1/8, 1/16 and so on. So the closest you can come to 1/10 is:

1/16 + 1/32 + 1/256 + 1/512 + 1/4096 + 1/8192 + ....

Or: 0.00011001100110011001100110011….

The net result is that the 32-bit floating point representation of 1/10 is actually 0.10000011324882507 (after rounding).

Pretty close, inn’t? It even looks absolutely correct after rounding to less than six digits. But it ain’t.

So, guess what happens when you try to take 0.5 (which *can* be represented exactly in binary) modulo 0.10000011324882507? The division of 0.5 by 0.10000011324882507 gives a quotient of 4 and a remainder of something like 0.099999547, and the later is displayed as 0.1

Working out the arithmetic with 18-digit decimal precision is left as an exercise for the reader.

Dec 11, 2010 at 6:49pm

PS: one solution is to stick to the integer domain as long as possible. Instead of doing [% 0.1], multiply your input by 100 (with rounding if appropriate) and do a [% 10], then divide the output by 100.0 when you’ve finished processing.

Dec 12, 2010 at 6:57am

where is peter when you need him.

ah, there he is.

as long as we are talking about %0.1 or %0.01 the chance to get a wrong result is exactly 0, isnt it?

the problem you describe only appears with fractions with periods, which i believe
noone would use with %, 0.33333334 just doesnt look integer enough even to the noob.

you only explained why the % object doesnt take float arguments, but i see no reason why
he should do *100 when you need %0.01.
of which we could argue if it exsists at all – but obviously you can get a result from using it.

as you stated yourself [expr 1.0 / 3.0] will also give you wrong results (from the perspective of
an int-thinker) so why bother about % 0.01?

furthermore, where is the excuse for [expr $f1%0.1] chrashing intel but not PPC?

i would exspect an “error: wrong expression” or something like that, like when you
attempt to calculate [expr log($f1,300)] or [expr bang>0].



You must be logged in to reply to this topic.