Shop OBEX P1 Docs P2 Docs Learn Events
Any ways to speed up Float32? - Page 5 — Parallax Forums

Any ways to speed up Float32?

1235»

Comments

  • MagnetspinMagnetspin Posts: 11
    edited 2014-10-16 02:20
    And this code can generate glitches:

    f32.atan2(f32.sin(Constant(PI)),f32.cos(Constant(PI)))) gives -Pi

    img_6562.jpg


    Magnetspin
    491 x 91 - 21K
  • kuronekokuroneko Posts: 3,623
    edited 2014-10-16 03:29
    Is using Float32 & Co for now not acceptable (until F32 is fixed)?
  • MagnetspinMagnetspin Posts: 11
    edited 2014-10-16 12:24
    it seems - jonatans pretty nice code needs some patches!
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-10-16 14:21
    It looks like the negative zero is messing things up a bit.
    Calculate(constant(pi))rad = 3.1415928 or = $40490FDB, F.Sin(rad) = -0 or = $80000000, F.cos(rad) = -1 or = $BF800000
    F32.ATan2(F.Sin(rad), F.Sin(rad)) = -3.1415928 or = $C0490FDB
    
    
    Calculate(pi)
    rad = 3.1415928 or = $40490FDB, F.Sin(rad) = -0 or = $80000000, F.cos(rad) = -1 or = $BF800000
    F32.ATan2(F.Sin(rad), F.Sin(rad)) = -3.1415928 or = $C0490FDB
    
    
    Calculate(3.132866)
    rad = 3.132866 or = $404880E0, F.Sin(rad) = 0.0087259256 or = $3C0EF72F, F.cos(rad) = -0.99996384 or = $BF7FFDA1
    F32.ATan2(F.Sin(rad), F.Sin(rad)) = 3.1328666 or = $404880E3
    
    
    Calculate(3.141593)
    rad = 3.141593 or = $40490FDC, F.Sin(rad) = -0 or = $80000000, F.cos(rad) = -1 or = $BF800000
    F32.ATan2(F.Sin(rad), F.Sin(rad)) = -3.1415928 or = $C0490FDB
    
    
    Calculate(3.1415926)
    rad = 3.1415928 or = $40490FDB, [COLOR=#ff0000]F.Sin(rad) = -0 or = $80000000[/COLOR], F.cos(rad) = -1 or = $BF800000
    F32.ATan2(F.Sin(rad), F.Sin(rad)) = -3.1415928 or = $C0490FDB
    
    
    Calculate(3.1415925)
    rad = 3.1415928 or = $40490FDB, F.Sin(rad) = -0 or = $80000000, F.cos(rad) = -1 or = $BF800000
    F32.ATan2(F.Sin(rad), F.Sin(rad)) = -3.1415928 or = $C0490FDB
    
    
    Calculate($40490fdd)
    rad = 3.1415932 or = $40490FDD, F.Sin(rad) = -0 or = $80000000, F.cos(rad) = -1.0000005 or = $BF800004
    F32.ATan2(F.Sin(rad), F.Sin(rad)) = -3.1415928 or = $C0490FDB
    
    
    Calculate($40490fdc)
    rad = 3.141593 or = $40490FDC, F.Sin(rad) = -0 or = $80000000, F.cos(rad) = -1 or = $BF800000
    F32.ATan2(F.Sin(rad), F.Sin(rad)) = -3.1415928 or = $C0490FDB
    
    
    Calculate($40490fdb)
    rad = 3.1415928 or = $40490FDB, [COLOR=#ff0000]F.Sin(rad) = -0 or = $80000000[/COLOR], F.cos(rad) = -1 or = $BF800000
    F32.ATan2(F.Sin(rad), F.Sin(rad)) = -3.1415928 or = $C0490FDB
    
    
    Calculate($40490fda)
    rad = 3.1415926 or = $40490FDA, F.Sin(rad) = 0 or = $00000000, [COLOR=#ff0000]F.cos(rad) = -1.0000005[/COLOR] or = $BF800004
    F32.ATan2(F.Sin(rad), F.Sin(rad)) = 3.1415928 or = $40490FDB
    
    
    Calculate($c0490fdd)
    rad = -3.1415932 or = $C0490FDD, F.Sin(rad) = 0 or = $00000000, F.cos(rad) = -1.0000005 or = $BF800004
    F32.ATan2(F.Sin(rad), F.Sin(rad)) = 3.1415928 or = $40490FDB
    
    
    Calculate($c0490fdc)
    rad = -3.141593 or = $C0490FDC, F.Sin(rad) = 0 or = $00000000, F.cos(rad) = -1 or = $BF800000
    F32.ATan2(F.Sin(rad), F.Sin(rad)) = 3.1415928 or = $40490FDB
    
    
    Calculate($c0490fdb)
    rad = -3.1415928 or = $C0490FDB, F.Sin(rad) = 0 or = $00000000, F.cos(rad) = -1 or = $BF800000
    F32.ATan2(F.Sin(rad), F.Sin(rad)) = 3.1415928 or = $40490FDB
    
    
    Calculate($c0490fda)
    rad = -3.1415926 or = $C0490FDA, F.Sin(rad) = -0 or = $80000000, F.cos(rad) = -1.0000005 or = $BF800004
    F32.ATan2(F.Sin(rad), F.Sin(rad)) = -3.1415928 or = $C0490FDB
    

    I was going to suggest using $40490FDA as pi (since it's actually the closest value without going over), but this causes trouble with the cosine method.

    BTW, here's a 32-bit floating point converter I found interesting and helpful.

    I'm not sure if floating point math on the Prop was ever expected to match the results one gets with a PC. I don't see a big problem with any of this.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-10-16 14:28
    Magnetspin wrote: »
    Ok
    The problem is solved now: Hanno found the error. His compiler used 3.141593, which equates to $40490FDC. He had to change this to $40490FDB.

    Thank to all for the support.

    In my recent tests, the Prop tool used $40490FDB for pi, I'm not sure this is the best value since as I mentioned above, $40490FDA is the largest approximation to pi without going over the value.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-10-16 14:32
    Here's some of the code I used to get the output in post #125.
    F32[PATH].Start                                                             FloatStr.SetPrecision(8)
    
    
      'Com.Lock
      NewLine
      Com.Str(DEBUG_COM, string("Calculate(constant(pi))"))
      Newline
      Calculate(constant(pi))
      NewLine
      Com.Str(DEBUG_COM, string("Calculate(pi)"))
      Newline
      Calculate(pi)
     
      NewLine
      Com.Str(DEBUG_COM, string("Calculate(3.132866)"))
      Newline
      Calculate(3.132866)
      NewLine
      Com.Str(DEBUG_COM, string("Calculate(3.141593)"))
      Newline
      Calculate(3.141593)
      NewLine
      Com.Str(DEBUG_COM, string("Calculate(3.1415926)"))
      Newline
      Calculate(3.1415926)
      NewLine
      Com.Str(DEBUG_COM, string("Calculate(3.1415925)"))
      Newline
      Calculate(3.1415925)
      NewLine
      Com.Str(DEBUG_COM, string("Calculate($40490fdd)"))
      Newline
      Calculate($40490fdd)
      NewLine
      Com.Str(DEBUG_COM, string("Calculate($40490fdc)"))
      Newline
      Calculate($40490fdc)
      NewLine
      Com.Str(DEBUG_COM, string("Calculate($40490fdb)"))
      Newline
      Calculate($40490fdb)
      NewLine
      Com.Str(DEBUG_COM, string("Calculate($40490fda)"))
      Newline
      Calculate($40490fda)
      NewLine
      Com.Str(DEBUG_COM, string("Calculate($c0490fdd)"))
      Newline
      Calculate($c0490fdd)
      NewLine
      Com.Str(DEBUG_COM, string("Calculate($c0490fdc)"))
      Newline
      Calculate($c0490fdc)
      NewLine
      Com.Str(DEBUG_COM, string("Calculate($c0490fdb)"))
      Newline
      Calculate($c0490fdb)
      NewLine
      Com.Str(DEBUG_COM, string("Calculate($c0490fda)"))
      Newline
      Calculate($c0490fda)
      
    

    The method "Calculate" is:
    PUB Calculate(rad) | temp0, temp1
    
    
    
    
      Com.Str(DEBUG_COM, string("rad = "))
      Com.Str(DEBUG_COM, FloatStr.FloatToString(rad))
      Com.Str(DEBUG_COM, string(" or = $"))
      Com.Hex(DEBUG_COM, rad, 8)
    
    
      temp0 := F32[PATH].Sin(rad)
      Com.Str(DEBUG_COM, string(", F.Sin(rad) = "))
      Com.Str(DEBUG_COM, FloatStr.FloatToString(temp0))
      Com.Str(DEBUG_COM, string(" or = $"))
      Com.Hex(DEBUG_COM, temp0, 8)
      temp1 := F32[PATH].Cos(rad)
      Com.Str(DEBUG_COM, string(", F.cos(rad) = "))
      Com.Str(DEBUG_COM, FloatStr.FloatToString(temp1))
      Com.Str(DEBUG_COM, string(" or = $"))
      Com.Hex(DEBUG_COM, temp1, 8)
      NewLine
      result := F32[PATH].ATan2(temp0, temp1)
      Com.Str(DEBUG_COM, string("F32.ATan2(F.Sin(rad), F.Sin(rad)) = "))
      Com.Str(DEBUG_COM, FloatStr.FloatToString(result))
      Com.Str(DEBUG_COM, string(" or = $"))
      Com.Hex(DEBUG_COM, result, 8)
      NewLine
      
    

    The method "NewLine" clears the end of the line and enter a carriage return.

    As seen in the output the compiler rounds some of the floating point numbers differently than the floating point objects.
  • ersmithersmith Posts: 5,919
    edited 2014-10-17 08:56
    Duane Degn wrote: »
    I'm not sure if floating point math on the Prop was ever expected to match the results one gets with a PC. I don't see a big problem with any of this.

    Actually it should match pretty closely for most purposes -- the IEEE floating point standard specifies exact results for the basic operations, and things built on top of these (like Sin and Cos) should be able to come up with the same answers, modulo some slight variation in the algorithms used for the trig functions.

    The PropGCC floating point libraries have passed a bunch of floating point tests, for both 32 and 64 bit floating point, so if you can switch from Spin to C you might get better results. Writing floating point code in a language that has built-in support is definitely easier (perhaps Spin 2.0 will make floating point more integral to the language).
Sign In or Register to comment.