Forums > MaxMSP

Bizarre number box behaviour


jg
October 3, 2008 | 12:52 pm

Here’s an extract from a patch I’m working on (in Max 5), which exhibits very odd behaviour from its number boxes.

Try opening this up, and type the number 1.045 into the number box at the top. On my computer, the result of this is that the float box on bottom left displays ’5.00000′ and the int box to the right of it displays ’4′, even tho’ they’re receiving exactly the same number! The int box will only change to read ’5′ when the float number is *higher* than 5 (e.g. 5.00001)

If you’re able to reproduce this… what’s going on?! As I understand it, this is not how int boxes are supposed to behave (in that they should truncate the float they receive, so ’5.00000′ should read ’5′!)

I attempted to reproduce this issue in a smaller patch which does not include any arithmetic operators or the split object, and it doesn’t recur.



jg
October 3, 2008 | 1:07 pm

Addendum… it appears to be a problem with the * box: the same problem happens when it’s the only arithmetic operator involved (no subtraction or split objects).



jg
October 3, 2008 | 1:25 pm

OK – disregard. It was just a result of the number box size: when I extended the float to its full size, it revealed that the number it was displaying was not 5, but 4.999996.

Still, that does leave me with this problem:

1.045 * 100 = 104.5

- 100 = 4.5

+ 0.5 = erm… 4.999996 :-)

Since I do need a surefire way of getting the int box to display *exactly* the right value, can anyone recommend a way of getting around the calculation limitations that cause this error?


October 3, 2008 | 1:40 pm

On 3 oct. 08, at 14:52, jg wrote:

>
> Here’s an extract from a patch I’m working on (in Max 5), which
> exhibits very odd behaviour from its number boxes.

There is no patch in your mail, so it’s a bit difficult to help…
But I suppose you need to learn a bit how floats work. There are
numerous posts on this list (Peter Castine’s are very instructive) or
you could check wikipedia:

http://en.wikipedia.org/wiki/Floating_point.

To be short, let say that 4.9999999 and 5.0000000 are the same
numbers. And this is a normal behavior which is not caused by Max.

p

_____________________________
Patrick Delges

Centre de Recherches et de Formation Musicales de Wallonie asbl

http://www.crfmw.be/max



jg
October 3, 2008 | 4:54 pm

Thanks for the suggestions, Patrick –
> To be short, let say that 4.9999999 and 5.0000000 are the same
> numbers. And this is a normal behavior which is not caused by Max.
Unfortunately, for the purposes of what I need to do they are not the same number, as an int number box will truncate them to very different values… But I’m aware there are methods of getting around the inevitable inaccuracies of floating-point calculation, so hopefully one of the posts you suggested will outline one I can use. All best



kjg
October 3, 2008 | 5:17 pm

before converting floats to int add 0.5

5.000000 + 0.5 = 5.500000 > truncates to 5
4.999999 + 0.5 = 5.499999 > truncates to 5

expr int($f1+0.5) is what i normally do in cases like this.



jg
October 3, 2008 | 8:02 pm

Quote: kjg wrote on Fri, 03 October 2008 11:17
—————————————————-
> before converting floats to int add 0.5
>
> 5.000000 + 0.5 = 5.500000 > truncates to 5
> 4.999999 + 0.5 = 5.499999 > truncates to 5
>
> expr int($f1+0.5) is what i normally do in cases like this.
—————————————————-

Yup, I already do this. Unfortunately, it does not solve the issue I mentioned before, which is caused by the inevitable inaccuracies of floating point calculation.

If there’s anyone else new to this issue, there’s a very neat little explanation in Peter Elsea’s tutorials (mentioned passim on this forum!) – goto http://cnmat.berkeley.edu/link/1319, and check out the tutorial about numbers.

He’s also written a very useful object, [lround], which does real rounding – and several other things besides.

Thanks to all.



kjg
October 3, 2008 | 8:07 pm

Quote: johngodfrey wrote on Fri, 03 October 2008 22:02
—————————————————-

> Yup, I already do this. Unfortunately, it does not solve the issue I mentioned before, which is caused by the inevitable inaccuracies of floating point calculation.

what exactly are you trying to do? maybe you should still post that patch. patches not working because of floating point rounding errors are usually just not designed too well..



jg
October 4, 2008 | 9:55 am

> what exactly are you trying to do? maybe you should still post that patch. patches not working because of floating point rounding errors are usually just not designed too well..

The little bit of patch that drew my attention to the problem couldn’t be simpler – it’s posted below. The problem is made explicit if you type 1.045 into the top number box…

The overall aim of the patch is to convert frequencies into equal-tempered pitches plus indication of cents deviation from normal. i.e. the frequency 196.2Hz is converted to ‘G3+2 cents’.

The little bit of patch below was part of the engine that calculated the cents part of this, and the floating point calculation was throwing up the wrong value (in the case cited above, it was giving the answer ‘G3+1 cents’

The use of lround has solved the problem for me, but perhaps there are more elegant ways of dealing with this :-) It’ll no doubt be an issue that comes up plenty… Any advice gratefully received.

{
"patcher" : {
"fileversion" : 1,
"rect" : [ 54.0, 94.0, 286.0, 249.0 ],
"bglocked" : 0,
"defrect" : [ 54.0, 94.0, 286.0, 249.0 ],
"openrect" : [ 0.0, 0.0, 0.0, 0.0 ],
"openinpresentation" : 0,
"default_fontsize" : 12.0,
"default_fontface" : 0,
"default_fontname" : "Arial",
"gridonopen" : 0,
"gridsize" : [ 15.0, 15.0 ],
"gridsnaponopen" : 0,
"toolbarvisible" : 1,
"boxanimatetime" : 200,
"imprint" : 0,
"metadata" : [ ],
"boxes" : [ {
"box" : {
"maxclass" : "number",
"outlettype" : [ "int", "bang" ],
"patching_rect" : [ 71.0, 189.0, 50.0, 20.0 ],
"id" : "obj-50",
"fontname" : "Arial",
"numinlets" : 1,
"fontsize" : 12.0,
"numoutlets" : 2
}

}
, {
"box" : {
"maxclass" : "flonum",
"outlettype" : [ "float", "bang" ],
"patching_rect" : [ 15.0, 189.0, 53.0, 20.0 ],
"id" : "obj-42",
"fontname" : "Arial",
"triangle" : 0,
"triscale" : 0.9,
"numinlets" : 1,
"htextcolor" : [ 0.870588, 0.870588, 0.870588, 1.0 ],
"fontsize" : 12.0,
"numoutlets" : 2,
"bgcolor" : [ 0.866667, 0.866667, 0.866667, 1.0 ]
}

}
, {
"box" : {
"maxclass" : "flonum",
"outlettype" : [ "float", "bang" ],
"patching_rect" : [ 155.0, 125.0, 53.0, 20.0 ],
"id" : "obj-41",
"fontname" : "Arial",
"triangle" : 0,
"triscale" : 0.9,
"numinlets" : 1,
"htextcolor" : [ 0.870588, 0.870588, 0.870588, 1.0 ],
"fontsize" : 12.0,
"numoutlets" : 2,
"bgcolor" : [ 0.866667, 0.866667, 0.866667, 1.0 ]
}

}
, {
"box" : {
"maxclass" : "number",
"outlettype" : [ "int", "bang" ],
"patching_rect" : [ 129.0, 191.0, 35.0, 17.0 ],
"id" : "obj-40",
"fontname" : "Arial",
"triscale" : 0.9,
"numinlets" : 1,
"htextcolor" : [ 0.870588, 0.870588, 0.870588, 1.0 ],
"fontsize" : 9.0,
"numoutlets" : 2,
"bgcolor" : [ 0.866667, 0.866667, 0.866667, 1.0 ]
}

}
, {
"box" : {
"maxclass" : "newobj",
"text" : "split 0. 50.",
"outlettype" : [ "float", "float" ],
"patching_rect" : [ 71.0, 125.0, 76.0, 17.0 ],
"id" : "obj-39",
"fontname" : "Arial",
"numinlets" : 3,
"fontsize" : 9.0,
"numoutlets" : 2
}

}
, {
"box" : {
"maxclass" : "newobj",
"text" : "- 100.",
"outlettype" : [ "float" ],
"patching_rect" : [ 96.0, 75.0, 34.0, 17.0 ],
"id" : "obj-37",
"fontname" : "Arial",
"numinlets" : 2,
"fontsize" : 9.0,
"numoutlets" : 1
}

}
, {
"box" : {
"maxclass" : "newobj",
"text" : "+ 0.5",
"outlettype" : [ "float" ],
"patching_rect" : [ 71.0, 162.0, 32.5, 17.0 ],
"id" : "obj-59",
"fontname" : "Arial",
"numinlets" : 2,
"fontsize" : 9.0,
"numoutlets" : 1
}

}
, {
"box" : {
"maxclass" : "newobj",
"text" : "* 100.",
"outlettype" : [ "float" ],
"patching_rect" : [ 96.0, 48.0, 34.0, 17.0 ],
"id" : "obj-57",
"fontname" : "Arial",
"numinlets" : 2,
"fontsize" : 9.0,
"numoutlets" : 1
}

}
, {
"box" : {
"maxclass" : "flonum",
"outlettype" : [ "float", "bang" ],
"patching_rect" : [ 97.0, 15.0, 53.0, 20.0 ],
"id" : "obj-56",
"fontname" : "Arial",
"triangle" : 0,
"triscale" : 0.9,
"numinlets" : 1,
"htextcolor" : [ 0.870588, 0.870588, 0.870588, 1.0 ],
"fontsize" : 12.0,
"numoutlets" : 2,
"bgcolor" : [ 0.866667, 0.866667, 0.866667, 1.0 ]
}

}
],
"lines" : [ {
"patchline" : {
"source" : [ "obj-56", 0 ],
"destination" : [ "obj-57", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-57", 0 ],
"destination" : [ "obj-37", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-37", 0 ],
"destination" : [ "obj-39", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-39", 1 ],
"destination" : [ "obj-40", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-39", 0 ],
"destination" : [ "obj-59", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-59", 0 ],
"destination" : [ "obj-42", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-59", 0 ],
"destination" : [ "obj-50", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-37", 0 ],
"destination" : [ "obj-41", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
]
}

}



kjg
October 4, 2008 | 2:29 pm

Quote: johngodfrey wrote on Sat, 04 October 2008 11:55
—————————————————-

> The overall aim of the patch is to convert frequencies into equal-tempered pitches plus indication of cents deviation from normal. i.e. the frequency 196.2Hz is converted to ‘G3+2 cents’.
>

Hi John,

I would do something like this. You can set a reference pitch different from 440 too. I think this patch is not "broken" due to rounding errors. Let me know if you find any problems. Hope it helps.

regards,
Klaas-Jan

#P window setfont "Sans Serif" 9.;
#P window linecount 2;
#P comment 275 161 247 196617 this does the same as [ftom 0.] except that you can set the reference freq to be something else than 440;
#P window linecount 1;
#P newex 288 111 48 196617 loadbang;
#P comment 344 135 46 196617 ref freq;
#P message 315 134 26 196617 442;
#P message 261 134 26 196617 438;
#P message 288 134 26 196617 440;
#P window linecount 2;
#P comment 169 374 174 196617 display as closest C4 note names + deviation positive or negative;
#P comment 178 271 201 196617 display as raw C4 note names + rounded deviation in cents;
#P window linecount 1;
#P comment 225 247 135 196617 deviation >> rounded cents;
#P comment 219 215 100 196617 deviation;
#P flonum 108 68 72 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P comment 218 191 130 196617 converted to note numbers;
#P newex 171 344 36 196617 – 100;
#P number 127 374 35 9 0 0 0 3 0 0 0 156 179 255 222 222 222 0 0 0;
#P number 91 374 35 9 0 0 4096 3 0 0 0 40 204 140 222 222 222 0 0 0;
#P newex 152 317 29 196617 t 1 i;
#P newex 108 317 29 196617 t 0 i;
#P newex 91 344 27 196617 +;
#P newex 108 294 54 196617 split 0 49;
#P message 12 124 26 196617 439;
#P message 39 124 26 196617 440;
#P message 66 124 26 196617 441;
#P number 136 271 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P number 99 271 35 9 0 0 4096 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 145 215 72 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 108 247 116 196617 expr int($f1*100+0.5);
#P flonum 145 191 72 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 108 186 31 196617 % 1.;
#P message 146 90 37 196617 196.2;
#P flonum 146 128 72 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 108 160 163 196617 expr 69+12*log($f1/$f2)/log(2);
#P window linecount 7;
#P comment 191 37 90 196617 freq input (note how 196.2 does not exist in 32 bit floating point – the closest number in binary is 196.199997);
#P fasten 1 0 14 0 113 182 96 182;
#P lcolor 7;
#P connect 14 0 17 0;
#P lcolor 7;
#P fasten 1 0 8 0 113 182 104 182;
#P lcolor 7;
#P connect 3 0 1 0;
#P connect 21 0 1 0;
#P connect 11 0 1 0;
#P connect 12 0 1 0;
#P connect 10 0 1 0;
#P connect 1 0 4 0;
#P connect 4 0 6 0;
#P lcolor 12;
#P connect 6 0 13 0;
#P lcolor 12;
#P connect 13 0 15 0;
#P lcolor 10;
#P connect 15 0 14 1;
#P lcolor 7;
#P connect 16 0 14 1;
#P lcolor 7;
#P connect 15 1 18 0;
#P lcolor 12;
#P connect 19 0 18 0;
#P lcolor 10;
#P connect 6 0 9 0;
#P lcolor 12;
#P connect 1 0 5 0;
#P connect 4 0 7 0;
#P connect 3 0 2 0;
#P connect 13 1 16 0;
#P lcolor 10;
#P connect 16 1 19 0;
#P lcolor 10;
#P connect 27 0 1 1;
#P connect 26 0 1 1;
#P connect 28 0 1 1;
#P connect 30 0 26 0;



jg
October 6, 2008 | 2:57 pm

Very nice! :-) Thanks for this – it was very interesting studying your solution. I had done the same maths, but your solution is much more elegant (most especially your method for deriving the deviation value!). And as you say, it doesn’t produce rounding errors (I’m going to spend some time tracking down the exact cause of the rounding errors in my original – useful to learn!).

Being able to alter the reference frequency was something I had intended to implement – it was great to see how you’d done it. I discovered that attributes in max 5 now let you do this quite easily in the ftom object also: [ftom 0. @base 442] for example.

Thanks again.


Viewing 11 posts - 1 through 11 (of 11 total)