#46286: AI likely weakened by integer overflow Open Date: 2022-12-16 08:09 Last Update: 2023-05-22 18:04 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-05-22 18:04 Updated by: Anonymous Comment: Another example of why we should use long ints for move rate stuff. --------------------------------------------------------------------- Ticket Status: Reporter: mortmann Owner: cazfi Type: Bugs Status: Closed Priority: 5 - Medium MileStone: 3.0.8 Component: AI Severity: 5 - Medium Resolution: Fixed --------------------------------------------------------------------- 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