Shop OBEX P1 Docs P2 Docs Learn Events
testing float if zero? — Parallax Forums

testing float if zero?

Rob v.d. bergRob v.d. berg Posts: 89
edited 2011-04-26 22:53 in Propeller 1
Hi,

I have (may be) a simple question: say there are 2 buttons, up and down. By pressing the up button, a tens (0.1) must be add to a float. By pressing down a tens must be submit from the float, till the float is 0.0 (zero).
What is the 'normal' way to test a float if zero?


This code works but .......

OBJ
F32 : "F32"

if ina(buttonDown)
if floatVar > 900_000_000 'this works, but the must be a better one
floatVar := F32.Fsub(FloatVar, 0.1)

if ina(buttonUp)
floatVar := F32.Fadd(FloatVar, 0.1)

any help?

Rob

Comments

  • lonesocklonesock Posts: 917
    edited 2011-04-26 13:20
    The floating point representation for 0 happens to be exactly the same as the integer representation of 0, so you can just check if floatVar == 0. That being said, you can run into small accumulated errors using floating point, so you might just want to increment and decrement an integer (maybe named "tenths" or similar), check if that is 0, and multiply that by 0.1 as needed. Alternatively (and more usefully if you happen to want the delta value to change some times) you can check to see if the floating point number is 0 to within a tolerance (1e-5 or something).

    Jonathan

    edit: if you just want to make sure the value never goes below 0, you could use:

    floatVar := F32.FMax(FloatVar, 0.0)
  • Rob v.d. bergRob v.d. berg Posts: 89
    edited 2011-04-26 13:36
    Jonathan,

    thanks, with a integer and than multiply by 0.1, thats i good one!

    Rob
  • JasonDorieJasonDorie Posts: 1,930
    edited 2011-04-26 15:20
    Just a minor addition to the negative test: A negative float just sets the highest bit, so you could test for negative by using:

    if( (FloatVal & $8000_0000) <> 0 )

    Or:

    if( (FloatVal >> 31) == 1 )

    You don't have to use the float library to check it this way, so it's faster.
  • localrogerlocalroger Posts: 3,452
    edited 2011-04-26 16:53
    You have a particular problem with the fraction 0.1; in binary, it's infinitely repeating, as 1/3 is in decimal. Since the float is only 32 bits wide it gets truncated, and it's not an exact representation. So if the float routines do not automatically round off for you, and you don't do it manually if they don't do it automatically, you get results like 1 / 10 * 10 = 0.99999999. These errors can cause the "zero" you're testing for to be slightly nonzero. Rounding can be computationally expensive, so the way you're doing it is actually a good solution.
  • max72max72 Posts: 1,155
    edited 2011-04-26 22:33
    If you add/subtract the same amount (0.1) you could use integers, using the counter multiplied by 10. This way you simply add/subtract 1.

    Massimo
  • SSteveSSteve Posts: 808
    edited 2011-04-26 22:53
    What Jonathan and Massimo are suggesting is called fixed point math (as opposed to floating point). If your application only needs a single digit beyond the decimal point, that's a perfect situation for fixed point math. You save a lot of processing power and probably a cog. All you do is use integers and change the units you're working with.

    For example, when I use the DS1620 thermometer the units I work with are tenths of degrees. If I want to see if two temperature readings are more than a degree apart, I compare the difference to 10 (tenths of a degree) instead of 1 (degree).
Sign In or Register to comment.