Search Unity

Two implementations which should give equivalent results but they don't

Discussion in 'Editor & General Support' started by Zimbo, Jul 22, 2013.

  1. Zimbo

    Zimbo

    Joined:
    Jul 11, 2012
    Posts:
    8
    Hi,

    This problem haunts me for over a week now. Pulling hairs out, almost getting mad. Ok, here it is, consider this C# code snippet:

    Code (csharp):
    1. public static float MidiNoteToPitch(int note){
    2.   bool works=false;
    3.   if(works){
    4.     return MidiNoteToPitch_Works(note);
    5.   }else{
    6.     return MidiNoteToPitch_Returns_NaN_sometimes(note);
    7.   }
    8. }
    9.        
    10. private static float MidiNoteToPitch_Works(int note){
    11.   if (note < 33) return 0.0f;
    12.   double strange=((double)note - 33.0) / InverseLog2 / 12.0;
    13.   float pitch = (float)(Math.Pow(10.0,strange) * 55.0);
    14.   return pitch;
    15. }
    16.        
    17. private static float MidiNoteToPitch_Returns_NaN_sometimes(int note){
    18.   double strange=33;
    19.   if (note < strange) return 0.0f;
    20.   float pitch = (float)(Math.Pow(10.0, ((((double)note - strange) / InverseLog2) / 12.0)) * 55.0);
    21.   return pitch;
    22. }
    Its rather self explanatory. If variable 'works' in method 'MidiNoteToPitch' is set to false, the method returns NaN in some cases.
    If 'works' is true, the method behaves normally in the same test cases. According to my nooby knowledge, there's no real functional difference in the implementations of MidiNoteToPitch_Works and MidiNoteToPitch_Returns_NaN_sometimes.

    The project is getting rather complicated, but now I don't do funny stuff with Threading. (Although I doubt even Threading can cause this type of problem, and I am afraid I need Threading in the future)

    Has anybody encountered something like this? Please help, I don't dare to proceed with the project before this mystery has been solved.

    Marco
     
  2. Graham-Dunnett

    Graham-Dunnett

    Administrator

    Joined:
    Jun 2, 2009
    Posts:
    4,287
    I've no idea what your maths is doing... or why it's so complicated. Note 33 is 55Hz, for sure. Add 12 notes, to get to 45 and you've got to 110Hz. So, 12 extra notes doubles your frequency, and that's an octave. You can turn that into maths, for sure. I'd cheat and just create an array indexed by note that returns the frequency. Seems infinitely easier than converting between floats,doubles and ints.
     
  3. Zimbo

    Zimbo

    Joined:
    Jul 11, 2012
    Posts:
    8
    Hi Graham,
    It's not about the math. (I do not understand the math myself, just found it somewhere on the internets). But without knowledge of advanced math, or mathematical music theory whatsoever, one can derive that MidiNoteToPitch_Works and MidiNoteToPitch_Returns_NaN_sometimes are the same function. They should return the same value, that is.
    The problem in my project (which has a lot... more code then this snippet) seems to treat the - logically and mathematically - same implementations totally different: One crashes and the other doesn't. That is what I don't understand. It probably has nothing to do with the code snippet itself, but with all the rest of my code.
    So my question is in fact: Did I screw something completely up in my C# coding, so badly, that it influences the behaviour of other, completely not related, classes? I know that Threading can cause these kind of problems, but that's not the case in this situation.
    I think i stated my original question in the wrong fashion, but i hope you understand my problem now.