2

I tested this on a empty project and does not happen.

Description

As you can see the newValue becomes 2.98023e-08 when I subtract the bossPercentage value. This happens only when bossPercentage is 0.2f and the previous value is 0.2f. The difference should be 0.0f but I don't understand why I get 2.98023e-08 instead.

For reference, remainingBossPercentage is a property in [GameController] class defined as following:

//header
@property (readwrite, nonatomic) float remainingBossPercentage;
//.m
@synthetize remainingBossPercentage;
//init
remainingBossPercentage=1.0f;

I'd like to ask you inisght on what I may be doing that causes this error.

EDIT: I subtract 0.2f to remainingBossPercentage (for each boss enemy) and everything works fine until I reach the last enemy object that has again 0.2f and I get to the crucial point of doing 0.2f - 0.2f (screenshot below)

EDIT 2: I am greatful for all comments and answers, also the closing votes. What induced me to ask this question is the fact that newValue is 2.98023e-08. I now see that there are also comparison issues (thanks to the extremely useful QA linked by the people that voted to close the answer). What I wonder is.. why in my new test project with only 2 test variables this does not happen? (I created a HelloWorld project that substracts two floats).

I am asking this because, as one of the user suggests, is important to understand floating points without taking shourtcuts. YES, I am taking a shortcut by asking this question because I don't have time tonight to study it properly but I would like to try understanding and learning at the best I can. I will read the answers properly and dedicate my time to understand but if in the meanwhile I can I would like to add a doubt:

could it be that for memory management reasons the two projects (the test one and my actual game) beheave differently? Could the different beheaviour of the two projects somehow linked with memory being swapped in dirty areas? (e.g. the game having bigger memory usage gets swapped more and hence there may be a loss of precision?)

PS: I found out a question with exactly the same 2.98023e-08 value. What I still wonder is why this doesn't happen in the same test project (I am doing some more testing now).

3
  • While this is a legitimate question it has been asked in many forms before and received good answers. Please take a look at floating-point-gui.de and the other questions here and stop expecting floats to be precise. Commented Nov 26, 2013 at 20:20
  • 1
    The only stupid question is the one you dont ask. Read, learn, keep asking. .02 Commented Nov 26, 2013 at 21:20
  • 2
    do a test project with (sorry, cant add an answer to make this clear) : float c=1.0; c=c-.2;c=c-.2;c=c-.2;c=c-.2; CCLOG(@"%.12f",c); the console should log -> main : 0.200000032783 <- , ie the floating point value accuracy you are getting depends on 'how' you get to it. If you do : float a=.2; float b=.2; float c=a-b; and log, you will get ->main : 0.000000000000 <-. Commented Nov 26, 2013 at 22:06

1 Answer 1

1

Simply, floating point numbers should not be expected to be completely accurate.

Floating point numbers (as used in our usual computers) are natively in base 2, out usual number is base 10. Not all numbers in one number base can be expressed with full accuracy in another number base.

As an empale 1/3 can not be expressed with complete accurate in the base 10 number system (0.333333...) but can be in the base 3 number system.

The upshot, one needs to compare floating point numbers with a specified error range. Take the absolute value of the difference and compare that to the allowable range.

Because of this financial amounts are generally not (should not be) expressed as floating point numbers. This give rise to classes such as NSDecimalNumber.

Sign up to request clarification or add additional context in comments.

3 Comments

It is not generally good to advise people to compare floating-point numbers within a specified error range. This either reduces false negatives at the expense of increasing false positives or vice-versa. Without knowing the requirements of a particular application, you cannot know whether this trade-off improves the situation or is acceptable. Therefore, it is bad advice. Proper advice is that software engineers planning to use floating-point must understand it and must design accordingly. They should not take shortcuts.
The best advice might be not to get oneself into such a situation. In some cases it is necessary, an example is XCTAssertEqualsWithAccuracy (a1, a2, accuracy, format…).
In this case, the best advice is probably to just use an integer between, say, 0 and 100.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.