Increase floating point accuracy for tiny input.

Vak Ath's icon

Hi,
I've recently installed the trial of MAX/MSP but I'm having trouble.
I am trying to input a tiny value (250*(10^-12)).
I have tried using the flonum item but it always rounds it to 0.
Any ideas?

nonlocality's icon
Max Patch
Copy patch and select New From Clipboard in Max.

you can set the number of decimal places a flonum it will show using the inspector! (or an attrui, like i did here)

Wetterberg's icon

but a main thing to remember is the value will still be there, it just won't be *displayed* - if you need it displayed you can always multiply it by a quadrillion or whatever.

Roman Thilenius's icon

not sure about 64, but in 32 bit max the closest value to 0.00000000025 is definitely 0.

Floating Point's icon
Max Patch
Copy patch and select New From Clipboard in Max.

hey roman I think there's no difference between 32-bit max and 64-bit wrt fp accuracy. i have 32-bit max and can represent that number:

the 32/64 thing in max is to do with memory addressing, not fp accuracy

Roman Thilenius's icon

well of course they are not releated to each other but i thought thats how the max builds work?
Version 6.0, and the 32-bit versions of Max 6.1, use 32-bit numeric data. The 64-bit version of Max 6.1 uses 64-bit numeric data for all message contents.
(https://cycling74.com/support/faq_max6/)

Roman Thilenius's icon

ah, look what i´ve done: *1000000 int (left "32 bit" branch).

not for the first time, isnt it?

Picture-9.jpg
jpg
vichug's icon

Roman, thanks to the link you gave i at last understand exactly what 32/64 bits means. (who would think to look at a FAQ in our days and age)

Floating Point's icon

Thanks Roman, evidently I was confusing max messages with msp signals. I shall now print out the faq and stick it to my forehead

Peter Castine's icon

Even with 32-bit floats, values down to 10^(-38) are represented (yes, thirty-eight decimal places). So any problems with representation are just that: representation on the screen.

Of course, Roman, if you go and tell Max to convert to int, those lovely decimal places are going to get eaten up (alas, English does not have a good word for "auffressen"). But whose fault is that?

---
EDIT: Just goes to show that I can make stupid mistakes when I'm in a hurry. Originally wrote "128 decimal places." Of course, it's 128 binary places (and I know this, arghhhh!). An exponent of 128 in binary is equivalent to about 38 decimal places. Still, you're good to go with your 10^(-25). You may need to start paying attention to interim calculations with these sorts of numbers, though.

So, I guess we're even Roman. Jut, fang an midder Lästerei.

Roman Thilenius's icon

it is actually - even if you know a bit about the theoretical background - quite hard to understand why this works (my patch, left brach, but without the /int mistake).

somehow one would exspect that expr, which is 64 bit internally, give you an other result than the basic lego bricks.

and yeah, that is another problem yet to be solved. things which work great for 1/4 might fail when you do 1/3. whats the cure? :)

Peter Castine's icon

There is a bit of fine-print in [expr] that affects your sample patch.

The arguments to [expr] are parsed into Atoms. With 32-bit Max, that means your 4,000,000,000 has to get squashed into a 32-bit float, which only has a 24-bit mantissa. But you need a full 32 bits in the mantissa to represent the 10-digit number. So you lose precision there. Then, even if the division is calculated with 64-bit precision, the result is sent as a message through a patch cord, so you're squashed again into a 32-bit float with the concomitant limits to precision.

As for 1/4 vs 1/3: all you really need to do to understand this is write the two fractions out as decimals: 0.25 vs. 0.333. Oops, the last one isn't quite exact, is it? Try writing a few more decimal places. You get to seven places, and it's still not exact. But you've used up all the precision for a mantissa in 32-bit floats. So, fine, switch up to 64-bits. That lets you write another almost fifty digits. Go ahead, write them down, it's a good exercise. But does it give you one third? Multiply by three and do you get back to one? (Really, you need to do this on paper to fully appreciate the situation.-)

Cures? Use Mathematica or MathLab or something else that does symbolic arithmetic manipulation. Or write your own symbolic manipulation objects (fun exercise for the reader).

If you think this is tricky, you should have worked with machine arithmetic in the '60s. <http://www.cs.berkeley.edu/~wkahan/ieee754status/754story.html> for some background

Roman Thilenius's icon

so there are actually not 1 but 2 errors in my attempt to explain something fundamental, very nice.

i kind of know that parsing the symbols(!) given to expr are cut off, but sometimes i think its fun to write for example a "64 bit" constants such as pi into expr, it gives you the feeling that at least the programmer has done all he can to get more accuracy.

but i must say that in the given case i dont fully understand it. i was using 4000000000 ... /1000000 just as on the left side, and exspected that the result should differ from using arithmetic objects. (which is does not, when done right, and not like above)

that the output of expr is cut down to 32 bits of precision is somehow exspected (you can tell because you may not write higher values into expr without brackets), but that 4000000000, (which can be displayed properly!) can not be parsed into the expr function without loss turns my picture of the universe upside down.

in the given case, it means that using expr resulted in a more inaccurate result than using 2 objects. :D

so in expr you had to use (40000. * 100000.) in order to receive the correct result. (see new picture, third branch.)

p.s. oh, about periods, well what i was thinking of is, that the only solution is either to change reality, or, in the case of a programming language, allow to transport and work with fractional numbers.
of course that´d be bullshit in max, because - at least for calculations such as ((1/3.)+(1/9.))*50 - with expr you can reach a more accurate result than with basic objects, and, what is the more important argument, the precision of 1/3 in 32 bit float is not worse than the precision of any other value scratching the range of 32 bit. plus max is 64 bit now and the situations where a user might think this is not enough became even less frequent than before.

-expr 110

bummer.jpg
jpg
Peter McCulloch's icon

FWIW, Bach has rational numbers if you need those. (mathematically speaking floats aren't irrational, but...)

Peter Castine's icon

@Roman: if you want the most accurate possible value for pi (rather than just pretending), you can use one of the trigonometric identities, like 2*asin(1). They are a bit expensive to calculate, and I think expr will recalculate them on every bang. But they should be calculated inside the expr object with double precision.

Peter's reminder of the bach library is a good point.

Roman Thilenius's icon

that´s interesting, danke.

that is why i am so good at finding solutions: i lack the theoretical background of things most of the time.