News:

Use the "Forum Search"
It may help you to find anything in the forum ;).

Discrepancies in calc_adjusted_monthly_figure

Started by PJMack, February 20, 2022, 09:32:59 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

PJMack

In adjusting maintenance costs I noticed a non-linearity between the maintenance cost specified in the dat file and what appears in the tooltip.  Upon further investigation, I found that in the version of the calc_adjusted_monthly_figure function invoked, integer division is performed before multiplication (simworld.h lines 1475-1476).  I noticed the 32 bit versions of this function perform the multiplication first then the division.  It occurred to me that the division first could have been deliberate as doing multiplication first would have the risk of overflow if the multiplicands are large.  A search of usage determined that this function is called in several places (even in game mechanics), so making any adjustment could have unintended consequences, particularly if a pakset was balanced whilst taking the error into account.  Does anyone have any insight to this?

jamespetts

Thank you for the report. It is certainly not intended for this to produce inconsistent results. I strongly suspect that division before multiplication in the 32-bit version is intended to prevent overflows as you surmise - I cannot remember exactly what I had in mind when I implemented this (or, indeed, whether it was me who implemented this at all).

Can you give some indication as to the sort of inconsistency that this produces?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

PJMack

I had found the problem by setting the maintenance cost of a bridge to 10, 100, 1000, then 10000 in the pak file giving results of 0.01, 0.16, 2.40, and 24.96 respectively verses the expected 0.02, .25, 2.50, and 25.00.  The display of maintenance costs calls this function for each cost, however when total finances are calculated, all the maintenance costs are summed, then this function is called.  The same version is also called when calculating factory passenger demand.

jamespetts

Thank you for noting this. The difference can be quite substantial for the smaller numbers. What we probably need to do is use 64 bits internally to allow the multiplication to happen before the division in this method so as to preserve precision. I am not sure how significantly that this will affect performance, however.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.