Mon, 17 Apr 2006

The Fun of Floating Point

Kernel people don't use floating point math much. I was once taken to task by Stephen Tweedie for asserting that FP is only used by people who don't care about the answers. Wesnoth avoids floating point math for a different reason: platform consistency. You really want units attacking power (ie. damage) to be equal on all platforms, and it's always expressed in terms of round numbers. So if your sword does 6 damage, but your opponent received 125% damage against blades and it's nighttime (-25%), the answer had better come out to be 6 on all platforms. Of course, calculations can be more complicated with multiple factors.

Even more importantly than not having an easier time on some strange architecture, if you're having a multiplayer game, you'd better all agree on what happens. So Wesnoth uses integer ops and open-multiplies them by 10000, etc. It's icky, but cleaning it up might introduce gratuitous incompatibilities. It also uses a new rounding mode on me: "round back to base value" in the case of rounding 0.5: so 6 + 0.5 => 6, and 6 - 0.5 => 6. Kinda ugly, but it's the same everywhere.

My attack_prediction code (which evaluates the likely damage distribution for an attack) uses doubles, because it's slightly faster in my benchmarks than 16-bit fixed point (as would be expected for a modern machine like my Pentium M laptop). Although it's possible that the AI could in future use this to make a different decision on some platforms, the current code uses random trials anyway, and a little unpredictability in the AI is a feature, anyway.

[/tech] permanent link