Shop OBEX P1 Docs P2 Docs Learn Events
Converting from Float to Integer — Parallax Forums

Converting from Float to Integer

3dogpottery3dogpottery Posts: 78
edited 2014-02-12 20:01 in Propeller 1
I am crunching some numbers using the F32 floating point code. My results are in a range between plus and minus 127.0 (a 32 bit floating point number). I need to send this result to a Motor Mind B, so it has to be converted to a one byte integer between plus and minus 127 (the minus 127 must first be converted to 2's compliment). The F32 library of functions does not have anything to accomplish this. I cannot find anything in the Propeller Manual that addresses this either. Does anybody know whether this is even possible?

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-02-12 14:12
    Spin only does negative number math with longs.

    As long as the floating point number is within the range -127 to +127, you should be able to use the "FRound" method or "FTrucn" method and just send the lest significant byte to the Motor Mind B.

    Here's one of many ways to do this.
    VAR
      long fLong, iByte
      byte iByte
    
    OBJ 
      F32 : "F32"
    
    PUB Main
    
      F32.Start
      fLong := -127.0
      iLong := F32.FRound(fLong)
    
      if iLong => -127 and iLong =< 127
        iByte := iLong
        ' send iByte to motor controller
      else
        ' display error
    
    

    By initially using a long to hold the value, you can accurately use comparisons with negative numbers.

    Besides using a byte sized variable, you could also use the "byte" command to access a single byte within a long. I don't use this often enough to remember the syntax without looking it up.

    Edit: I initially used the "FloatRound" instead of "FRound". They are not the same. "FloatRound" leaves the number encoded as a float.
  • John AbshierJohn Abshier Posts: 1,116
    edited 2014-02-12 14:16
    It's possible. Here is some untested thoughts. i := F.FTrunc(FloatValue) will put and integer representation of FloatValue into i with truncation, drop fractional part. Or you could use FRound. Just looked at the Motor Mind B manual. It uses a command for forward or reverse and a speed of 0-255.

    if i => 0
    send forward command
    send i.byte[0] * 2 ' multiply by 2 since your max value is 127 and Motor Mind B max value is 255
    else
    send reverse command
    send (i.byte[0] & $7F) * 2 ' & $7F to get rid of sign bit and rescale

    John Abshier
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-02-12 14:43
    send (i.byte[0] & $7F) * 2 ' & $7F to get rid of sign bit and rescale

    I don't think your code would work as expected.
    127 in binary is b0111_1111
    -127 is b10000001
    I'm using "b" instead of the percent sign so I can keep using the WYSIWYG editor.
    I think your code would convert -127 to 2.

    Spin does have an absolute value operator "||". Another option would be to multiple the number by negative one.

    Edit: BTW, John is showing how to use a single byte in a long.
  • 3dogpottery3dogpottery Posts: 78
    edited 2014-02-12 14:51
    I don't need to convert a negative float value to an integer. In my code, I use the absolute value of the float, and set a flag if the original number was negative. If the flag is set, subsequent code converts the number to 2's complement by taking the complement of the number, and adding one. So, all I need to do is convert a float value between 0 an 127 to a byte integer. Anyway, in the mean time, I am looking at the suggestions kindly submitted...
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-02-12 15:02
    So, all I need to do is convert a float value between 0 an 127 to a byte integer.

    The method "FRound" will convert a float to an integer. You just stick the resulting number in a byte sized variable or use a single byte of the long (or word) in which it's stored.
    byte positive integers aren't encoded differently than long positive integers.
  • 3dogpottery3dogpottery Posts: 78
    edited 2014-02-12 15:20
    Ok! Thanks for the suggestion Dwane. The following code works....

    [ code ]

    VAR

    long Along
    byte Abyte
    PUB
    Along := 114.2

    if (Along => 0)
    Abyte := F32.FRound(F32.FMul( F32.FAbs(Along), 127.0))
    else
    Abyte := !F32.FRound(F32.FMul(F32.FAbs(Along), 127.0)) + 1


    [ /code ]

    I didn't realize that FRound returned an integer. I assumed that it rounded a float, and returned a float. But of course, if you round a float, you are dropping the fractional part of the number. Naturally, the result is an integer.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-02-12 16:43
    I didn't realize that FRound returned an integer. I assumed that it rounded a float, and returned a float. But of course, if you round a float, you are dropping the fractional part of the number. Naturally, the result is an integer.

    The "FloatRound" method does return a floating point number. It drops the fractional part of the number but keeps the number encoded as a float. There are two different "Round" methods in F32. One returns an integer and the other a floating point number.

    BTW, you need to remove the spaces in your code tags. [ code ] should be [code]. You also need to remove the spaces in closing tag.
  • AribaAriba Posts: 2,690
    edited 2014-02-12 17:11
    if (Along => 0)
    Abyte := F32.FRound(F32.FMul( F32.FAbs(Along), 127.0))
    else
    Abyte := !F32.FRound(F32.FMul(F32.FAbs(Along), 127.0)) + 1

    FRound can handle also negative numbers so I think you can replace this with:
    Abyte := F32.FRound(F32.FMul(Along, 127.0))
    
    If you want to show the byte value in a terminal you need the sign extend operator to see the negative number:
    term.dec(~Abyte)

    Andy
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-02-12 17:34
    Ariba wrote: »
    If you want to show the byte value in a terminal you need the sign extend operator to see the negative number:
    term.dec(~Abyte)

    Andy, I thought you need to start with a 16-bit number to use sign extend?

    Am I missing something (as I often do)?
  • AribaAriba Posts: 2,690
    edited 2014-02-12 19:53
    Duane Degn wrote: »
    Andy, I thought you need to start with a 16-bit number to use sign extend?

    Am I missing something (as I often do)?

    Yes you miss a tilde :smile:

    One tilde for sign extend from a byte.
    Two tildes for sign extend from a word

    Andy
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-02-12 20:01
    Ariba wrote: »
    Yes you miss a tilde :smile:

    One tilde for sign extend from a byte.
    Two tildes for sign extend from a word

    Andy

    Wow, I did not know that. Thank you!
Sign In or Register to comment.