[Freeciv-tickets] [freeciv] #46286: AI likely weakened by integer overflow

Back to archive index
OSDN Ticket System norep****@osdn*****
Tue Feb 28 21:42:57 JST 2023


#46286: AI likely weakened by integer overflow

  Open Date: 2022-12-16 00:09
Last Update: 2023-02-28 13:42

URL for this Ticket:
    https://osdn.net//projects/freeciv/ticket/46286
RSS feed for this Ticket:
    https://osdn.net/ticket/ticket_rss.php?group_id=12505&tid=46286

---------------------------------------------------------------------

Last Changes/Comment on this Ticket:
2023-02-28 13:42 Updated by: alain_bkr

Comment:

i vote for float
it seems the simplest change, and may fix other similar issues elsewhere in the code.
All current CPU have floating point unit (since 1995 ?)


---------------------------------------------------------------------
Ticket Status:

      Reporter: mortmann
         Owner: (None)
          Type: Bugs
        Status: Open
      Priority: 5 - Medium
     MileStone: 3.0.7
     Component: AI
      Severity: 5 - Medium
    Resolution: None
---------------------------------------------------------------------

Ticket details:

AI desire to kill likely weakened by integer overflow in ai/default/aiunit.c:kill_desire()
Depending on input values, instead of returning a big positive value for desire to kill, it returns a negative one.
Even if freeciv is compiled on 64 bit systems, the integer calculation is performed 32 bit.
Random example from a real game:
input values for kill_desire():
int benefit = 7824
int attack =  6400
int loss = 50
int vuln = 12544
int victim_count = 3
SHIELD_WEIGHTING = 17 by #define
Current formula:
desire = ((benefit * attack - loss * vuln) * victim_count * SHIELD_WEIGHTING / (attack + vuln * victim_count));
result: desire =  -40270
Ive got 2 ideas how so solve it:
1. Mitigate the overflow, cap the value of (benefit * attack - loss * vuln) * victim_count so that the overflow wont happen, like:
desire = (benefit * attack - loss * vuln) * victim_count;`

if (desire < (INT_MAX / SHIELD_WEIGHTING)) { /* mitigate signed integer overflow */
  desire *= SHIELD_WEIGHTING;
} else {
  desire = INT_MAX;
}
result: desire = 48770
Theoretically the overflow could still happen before multiplying with SHIELD_WEIGHTING, but it would be an improvement over the more easily triggered overflows happening right now. The cases ive seen in real game, would be mitigated.
2. Fix the overflow for systems, that have long to be 64 bit:
desire = (long) (benefit * attack - loss * vuln) * victim_count * SHIELD_WEIGHTING / (attack + vuln * victim_count);
result: desire = 57271
I quickly went over the source code, and i dont see any 64 bit stuff happening. Also i dont know how you handle portability and such in freeciv. Thats why i didnt propose the use of int64_t here. Can you find better solutions?

-- 
Ticket information of Freeciv project
Freeciv Project is hosted on OSDN

Project URL: https://osdn.net/projects/freeciv/
OSDN: https://osdn.net

URL for this Ticket:
    https://osdn.net/projects/freeciv/ticket/46286
RSS feed for this Ticket:
    https://osdn.net/ticket/ticket_rss.php?group_id=12505&tid=46286



More information about the Freeciv-tickets mailing list
Back to archive index