LAE

Welcome to the LAE community!  Please feel free to start a discussion in the discussion tab or join in a conversation.

Discussions

Members

Resources

Events

 View Only
  • 1.  Comparing Floats

    Employee
    Posted 05-07-2008 21:56

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: ejones

    I\'m a little hesetant to call this a bug, but the more I think about it, the more I\'m convinced it is. But it is more of a design problem.

    Floating point numbers should never be compared with == for equality. This is because of round off errors. The attached graph demonstrates this. It is ok to compare with < and > but not ==. I\'m going back and forth in my thinking about <= and >=.

    I\'ve been thinking of several solutions.
    1. Create a Fixed datatype for situations where we are dealing with money. Oracle does this and internally uses a base 100 number where each byte represents a base 100 digit.
    2. Don\'t allow == on floating point numbers and instead require the user to round or do some comparison of closeness. Something like Abs(a-b) < 0.0005 would be allowed or round(a,-5) == round(b,-5).
    3. Don\'t allow == on floating point numbers and instead create a new equality test that indicates how close the floating point numbers are. For example we might use ==0.0005== to indicate that the floating point numbers are within epsilon = 0.0005 from each other.

    Attachments:
    Comparing_Doubles_Problem.brg


  • 2.  RE: Comparing Floats

    Employee
    Posted 05-08-2008 19:33

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: rboccuzzi

    That is correct, equality comparisons with regards to floating point numbers can be dangerous. This is true in BRAIN, as in most languages. Both >= and <= also have the same issue.

    There is an epsilon parameter in the sort node, and a third parameter that can be passed into the cmp function, which will specify the epsilon to use to determine if two floating point numbers are equal, but you should be cautious with their use or avoid it all together. Unexpected behavior can occur, and you are better off just using < and >.

    Think about this: if you have three numbers, 1.2, 1.3, and 1.4, and an epsilon value of .1, then 1.2 == 1.3, and 1.3 == 1.4, but 1.2 != 1.4. This lack of transitivity on the equality of floating points with epsilon can cause issues in the sort node when not doing stable sort, and unexpected behavior in general.

    We have provided the tools, but only for use if all else fails, and don't recommend using them. In most cases, you can use < or > to do what you need to, or convert a floating point number to a ranged integer (fixed point) and compare those.

    $Rich


  • 3.  RE: Comparing Floats

    Employee
    Posted 06-30-2008 19:32

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: ejones

    Is there some documentation or examples of what you mean by "ranged integer (fixed point)" numbers? I would like to start using these for currency instead of using floating point numbers.


  • 4.  RE: Comparing Floats

    Employee
    Posted 07-09-2008 18:12

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: rboccuzzi

    We don't have any fixed point libraries built into BRAIN at this time, but we do have a reasonably rich math library, so google around for any standard math that might apply to your specific problem, and you can probably enact it in BRAINscript.

    I don't know about your specific problem, So for example, when I meant ranged numbers, was something simple, if you have certain ranges of floating points that could occur, do comparison (not ==, but < or &gt to identify a range for a number, and give it an integer value. This can be as simple or complex as you need, but coded to your particular problem.

    In the case of money, as you mentioned, it might be as simple as storing all numbers as cents in integer form, instead of floating point. This may be sufficient, depending on the operations that you do on them. Obviously if you are doing percentage rates on them (like interest rates), you will still be "losing" fractions of cents if you do this. That may be acceptable in your application, or not even applicable. I hope this helps.

    $Rich