#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