Reputation: 9442
What's going on?! Subtraction works fine until I get to 0.1 - 0.1. I'm in visual c# 2008 using the nonoba.com API.
Console.WriteLine("hit! " + Users[targetNum].character.health + " : " + player.character.profile.attackPower);
Users[targetNum].character.health -= player.character.profile.attackPower;
Console.WriteLine("health! " + Users[targetNum].character.health);
output:
hit! 0.1 : 0.1
health! 1.490116E-08
Thanks all - I might use the decimal type, as I'm normally adding/subtracting nice "round" numbers. For now I'll just go with:
if (Users[targetNum].character.health <= 0.00001)
By the way I knew this wasn't really going to be a "bug" in c# - I thought it would either by a bug in my code or some lack of understanding, which it was.
Having read all the recommended reading, I'm going to conclude that my folly was due to normally using the ActionScript Number type, which maybe has a decimal rather than binary floating point - anyway, it would never give this output.
Upvotes: 0
Views: 5216
Reputation: 1062895
That seems pretty normal for floating point math... you always have to check against a small delta to account for imperceptible rounding differences. Depending on the scenario, decimal
might be what you want.
Basically, unless you can be sure that it is exactly the same 0.1 in both cases (i.e. nothing has been done to them), you aren't likely to get zero; in general you'll get something very nearly zero. With decimal
you'll usually get more what you expect intuitively.
See also Jon Skeet's pages here:
Upvotes: 17
Reputation: 308763
You obviously need to read "What Every Computer Scientist Should Know About Floating Point Numbers".
Instead of thinking that I've found a bug in situations like this, I usually assume that one of my assumptions needs checking first.
Upvotes: 12
Reputation: 181785
Slighly offtopic, but here's an interesting read that describes why cos(x) != cos(y)
can be true even if x == y
:
http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18
Upvotes: 0
Reputation: 993223
If you're always adding and subtracting "nice round" numbers, that is tenths or hundredths, then you can keep track of your hit and health values in integer tenths-of-units. An analogy is a financial program that keeps track of money in integer cents, instead of floating point dollars. Using integers avoids all the problems of floating point math.
Upvotes: 1
Reputation: 10141
Floating point math is always approximate, in any language, because that's how CPUs work. If you care about the absolute precision of your answers - for example, because you're dealing with money - then you shouldn't use floating point.
Upvotes: 0