sig math error (bug?) w/ [log~ 2] -> [trunc~]

cudnylon's icon

was adapting an expression for rounding down to a power of 2 from [expr] to signal rate when i came across this problem. when given the integers 8, 64, 128, 4096, ... [log~ 2] returns an integer but [trunc~] rounds it down instead of returning the same value. i've come up with a fix for values < 8192 but still wonder what the issue is / if anyone else gets the same results.

(note: i see that at 8192 and 32768 the [expr] breaks down as well at the "int" stage)

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

also this is for a weird patch, i know i could do this easier and not at signal rate in a different context

Pierre Guillot's icon

Hi,
I noticed the same problem. Do you use Max5 or Max6? Have you a 64 bit computer?

Peter Castine's icon

Don't trunc~, round.

ie: [log~ 2] -> [+~ 0.5] -> [trunc~].

It is a fundamental fact of life with digital numerics that you will always have precision issues with the LSBs. log~ does its stuff by using a Taylor series approximation for whatever (arbitrary) input value the function may be given. So log(16) will wind up as 3.999999999998 or 4.0000000000001 or whatever, but never as 4.000000000000000000000000000000000… Using 64 bits only delays the inaccuracy but doesn't avoid it entirely.

Peter Elsea wrote a useful and highly recommended tutorial on the gotchas of Floating Point Arithmetic years ago, and everybody will save themselves a lot of grief with digital math if you can track it down.

cudnylon's icon

i'm running max 6 on mac os x 10.7.3

[log~ 2] -> [+~ 0.5] -> [trunc~] fixes the problem at some values but gives the wrong results in other places. 3 returns 4, 7 returns 8, etc. i'll definitely check out that tutorial. found it here: ftp://arts.ucsc.edu/pub/ems/maxtutors/Max&Numbers.pdf very informative.

i've come up with an improved fix for the problem plus replaced [trunc~] with [round~ 1. @nearest 0] for no reason other than assuming it will be easier on the cpu (trunc~ is "computationally expensive").

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

i compare the input with the output multiplied by 2. whenever they match then an error has occurred and the output is corrected. this works for very high values. since this works for the patch and the error isn't a "bug", the case is closed.