Menu

#31 bad rounding for unit properties when merging

open
nobody
None
5
2012-03-27
2012-03-27
No

When units are merged, the new property values are calculated like this:

unit->property = (int) (weight1 * unit->property + weight2 * source->property);

However, casting from float to int truncates the float value, which might yield bad values in some cases. For example, unit has strength 7, source has strength 5. The air defense value of both units is 7. Now the expression

weight1 * unit->property + weight2 * source->property

yields around 6.9999995231. The explicit cast (int) truncates this to 6, the new value for the merged unit.

The attachment is a saved game with this situation: merge the two units on (5,11) and (5,12). The new unit's air defense value is 6, while both units had the value 7 before.

Discussion

  • mranderson2007

    mranderson2007 - 2012-03-27

    saved game demonstrating the bug

     
  • mranderson2007

    mranderson2007 - 2012-03-30

    As solution, I suggest calculating the new values with integer operations only. Something like this:

    int new_strength = unit->str + source->str;
    (unit->str * unit->property + source->str * source->property) / new_strength;

     

Log in to post a comment.