signal division bug??


    Mar 27 2008 | 11:52 am
    try to divide a signal with itself!!! it does not produce always 1.000 this doesn't happen with the non signal object! is this a bug of some kind or normal behavior? check out the following very simple patch and try numbers that are a power of 2 and numbers that are not and you will see what I mean... this also happens with the !/~ object. any suggestions on why is this happening and any workarounds?
    gs

    • Mar 27 2008 | 1:49 pm
      On 27 mars 08, at 12:52, hmutant wrote:
      > try to divide a signal with itself!!!
      I generally have better things to do ;-)
      > it does not produce always 1.000 > this doesn't happen with the non signal object!
      This is not true. 7.97 is OK on my system for the DSP part of your patch, but not for the Max part. For 7.92, it's the opposite.
      > is this a bug of some kind or normal behavior?
      It's normal.
      _____________________________ Patrick Delges
      Centre de Recherches et de Formation Musicales de Wallonie asbl http://www.crfmw.be/max
    • Mar 27 2008 | 3:05 pm
      you are right about the fact that the non signal object also produces wrong results in certain cases but not for the same numbers as in your system!!
      It doesn't seem normal.
      I created a java class for use with mxj~ and a C++ external for windows that perform a simple division like the /~ object. They are working fine whatever number you feed them. The result is always 1 and the test [==~ 1] always results to true! If it is normal behavior just for the cycling's objects for some reason I don't understand, could someone explain it to me? Anyway shouldn't at least be consistent between different OS and between signal and non signal objects? How can I predict if it is going to work on a different machine than mine?
      It is not just a philosophical question. If you try to quantize a number you need to perform this kind of operation, and the fact that the result is not the same on every machine makes it very difficult to develop a reliable application
      gs
    • Mar 27 2008 | 9:51 pm
      This is not a bug but an artifact of how finite-precision floating point arithmetic works.
      Google the list a bit about floating point precision. Check out Peter Elsea's tutorial on the subject while you're at it. Reading the fine print on optimizations in the /~ object is also worthwhile.
      The answer is insanely obvious if you understand how the /~ object works and a little bit about numeric arithmetic. But I don't want to give away the punch line.
    • Mar 28 2008 | 2:31 pm
      I read some parts of Peter Elsea's tutorials and they are very nice and informative... I need to read them more carefully when I find some time.
      Still... I don't understand what finite precision of floats (32Bit or 64Bit or any precision) have to do with what I am experiencing with the [/] objects!!
      If it is a finite precision problem, since in all systems Max AND MSP use floating point numbers of the same precision shouldn't always produce the same result? Why is it system dependent???? This doesn't happen in jitter using [jit.op] and float32 or float64 type of matrix!!! If it was due to finite precision it should produce the same results in jitter too!!! The [expr] object in MAX also works fine in my system. There is also an inconsistency between the [== 1.0] object and the [if $f1==1.0] object (check out the patch below). The [if] object seems to work better. Can someone explain which objects use what types of variables in each system so we can know what kind of casting occurs each time? I think max msp should be able to handle things like that in a more consistent way.
      In other programming languages like C++, java... the division and comparison operators give the correct result when dividing a floating point number with itself. As long as you are not mixing different types of variables (single precision with double or int) comparing the result with 1.0 (1.0 being of the same type) results always to true. I understand that 1.0 as a float is not equal to 1 as integer because of finite precision. But since the comparison is performed with the same type (float32) as the result of the division, this should not be a problem. Correct me if I am wrong, but I tested it that in C++, java and jitter (see the patch bellow) with 32bit floats (it works also with 64bit floats).
      thanks a lot for your patience this was a loooooong one George
    • Mar 28 2008 | 10:15 pm
      /~ optimizes division by a constant. Float division is expensive, taking about five times longer than float multiplication.
      So [/~ 3] does not divide every sample by three. It calculates the inverse (1.0/3.0) once and only once and stores the result, then multiplies every incoming sample by 0.333333 (actually more like 0.333332975).
      I said you needed to read the fine print of /~. Cf. p.17 MSP Reference Manual.
      I really oughta start charging for this.
    • Mar 29 2008 | 10:27 am
      Anyhow, this implies that only with integers it is safe to do comparisons. Floats should be tested for being within some range. The ==~ object is of an optimistic kind.
      _ johan
    • Mar 29 2008 | 11:11 am
      I was taught 40 years ago to never compare floating point values for equality. If you're going to test, do something like abs(x-y)
      This is the first rule of digital floating point arithmetic. Learn it.
      The second rule is "never say never" and since the development and implementation of the IEEE 754 standard you can actually test floats for equality. Sometimes. Knowing when is advanced programming. If you haven't learned the first rule yet, don't even think about the second one.