Shop OBEX P1 Docs P2 Docs Learn Events
Problems with numbers — Parallax Forums

Problems with numbers

g3cwig3cwi Posts: 262
edited 2012-02-04 16:05 in Propeller 1
Hi all

The following code seems to have a problem. If Fout is an integer, all is well, however changing it to a decimal, even going from 7 to 7.0 causes the code to give odd results. I have tried using the F32 object to round, truc and other things but that gives yet more confusing results. There must be something really obvious that I am missing - but I have no idea what.
OBJ
  pst   :       "Parallax Serial Terminal"
  fpm   :       "F32" 'Load Float Routines



Var

Long Fout, Fclock, f, fw

Con

Divisor=34359738.4

PUB Main | value, base, width, offset
  pst.Start(115_200)


  '__________________ Test my code

  Fout := 7 'Test data
 Fclock := 125 'Test data
 f := 0 'Hard clear f
 fpm.start
 
'Calculate the frequency word required
 
   Fout <<= 1
  repeat 32   'perform long division of (Fout / Fclock) * 2^32
    f <<= 1
    if Fout => Fclock
      Fout -= Fclock
      f++           
    Fout <<= 1
f:=f+1
fw:=f
    
 waitcnt(clkfreq*5+cnt)

    pst.Clear
    pst.Chars(pst#NL, 1)
    pst.Dec(f)
    pst.Chars(pst#NL, 2)
    pst.Dec(fw)
    pst.Chars(pst#NL, 1)
    pst.Hex(fw, 8)
    pst.Chars(pst#NL, 1)
    pst.Bin(fw,32)
    pst.Chars(pst#NL, 1)
    Pst.dec(cnt)
    

Any ideas?

Thanks

Richard

Comments

  • Mark_TMark_T Posts: 1,981
    edited 2012-02-04 12:35
    Floating point values can only be operated on by a floating point library (+, -, *, <<, >> etc won't do what you expect) as I understand it.

    Why not post the code that doesn't work and explain exactly what you expect it to do ?
  • g3cwig3cwi Posts: 262
    edited 2012-02-04 12:43
    Hi Mark

    I did post the code in my first post.

    Fout = 7 should give 240518169 (it does)

    However Fout = 7.0 gives 2118123644
  • Mike GreenMike Green Posts: 23,101
    edited 2012-02-04 12:58
    Fout := 7.0 should display as 2118123644 because the decimal output routine only handles integers. The Spin compiler translates the floating point value to its internal integer equivalent which is 2118123644. As Mark_T indicated, you have to use the floating point library to do floating point operations and there are separate floating point input and output routines that convert strings to floating point values and back again.

    Look at this object and this one. Note that in the 2nd object, you should change the reference to the FloatMath object to use F32 instead which is a faster drop-in replacement.
  • StefanL38StefanL38 Posts: 2,292
    edited 2012-02-04 13:00
    as Mark_T has mentioned

    if you want to do calculations with numbers stored as floating point you have to use the methods for "plus", "minus", "multiply" and "divide" that are inside
    the floatingpoint-object F32.

    the propeller can handle only 32bit integers. Even a floating-point value is stored in a 32bit integer. But the meaning of the bits is different to the meaning
    of bits in a long. So first of all a long-value has to be transformed into a floating-point value and after that all mathematical operations must be done with floating-point methods

    see the following methods inside the file F32.spin
    PUB FAdd(a, b)
    PUB FSub(a, b)
    PUB FMul(a, b)
    PUB FDiv(a, b)
    PUB FFloat(n)
    
    best regards
    Stefan
  • ratronicratronic Posts: 1,451
    edited 2012-02-04 13:55
    g3cwi here is just a demo of dividing 2 floating point#'s and displaying them on the serial terminal.
    Con                                                          
                                                             
      _CLKMODE = XTAL1 + PLL16X                              
      _XINFREQ = 5_000_000  
      
    Var
                             
    Obj                                                      
      pst : "parallax serial terminal"
      fm  : "floatmath"
      fs  : "floatstring"
          
    Pub main | a, b, c
      pst.start(115200)
      a := 7.0
      b := 34359738.4
      c := fm.fdiv(a, b)    'divide a by b
      pst.str(fs.floattostring(c))  'display floating point #
    

    Edit: integers must be turned into floats to do math with other floats by using the .ffloat method in floatmath
  • ChrisGaddChrisGadd Posts: 310
    edited 2012-02-04 14:25
    Do you really need floating point numbers? Assuming this is for the AD9851 register setting, rather than using 125 as the clock freq and 7.01234 as the output freq, could you use 125_000_000 and 7_012_340 instead?
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-02-04 14:35
    If you use pseudo real numbers, as Chris suggests, you ought to take a look at this thread. I posted a method (in post #4) to display pseudo real numbers with a decimal point.
  • g3cwig3cwi Posts: 262
    edited 2012-02-04 16:05
    Chris

    Thanks. That's the solution I needed. I am making slow but steady progress - this is new to me so the patient help is appreciated!

    Cheers.
Sign In or Register to comment.