Iain
Iain

Reputation: 9442

C# float bug? 0.1 - 0.1 = 1.490116E-08

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

Answers (5)

Marc Gravell
Marc Gravell

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

duffymo
duffymo

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

Thomas
Thomas

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

Greg Hewgill
Greg Hewgill

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

Marcus Downing
Marcus Downing

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

Related Questions