ERP5 KM

DiscussionFloatRounding

This section in the python tutorial can be interesting.

Bruce M. Bush's from Lahey article is covering many aspects of float rounding.

A TechnicalNoteOnRoundingInAccounting page is in progress.

Problem

* Problem 1: ratios applied to amounts must be rounded for accounting. (ex. 19.6% of 0.10 EUR = 0.02 EUR)

* Problem 2: 0.22 + 0.11 + 0.11 = 0.44 and not 0.43999999999999

* Problem 3: round(a) + round(b) is not round(a + b)

* Problem 4: total_price must be rounded if currency

* Problem 5: 100000000000000000000000000000001 = 100000000000000000000000000000000 with floats

Solution

* Solution 1: use currency object to round for given currency (in applied rules, in scripts, in total price) ie. wherever the amount uses a currency. The result is a python decimal object. Ex. getTotalPrice returns a decimal object.

* Solution 1b: use 64 bit integers (in cents, in millims)

* Solution 2: add a decimal_quantity to MySQL stock table. Make total_price a decimal in MySQL. If necessary,only index decimal_quantity for certain portal types. A simple float rounding problem can be seen with this python code:

>>> 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1
0.99999999999999989
>>> 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 == 1
False

* Solution 3: extend getInventory API to produce all types of balances and histories with decimals

* Solution 4a: add a decimal type to propertysheet and use my_decimal_quantity in forms

* Solution 4b: add a decimal widget and replace float widget with decimal widget for certain my_quantity

* Another idea: Use longs, multiply them by 1/resource_precision.

  •    precision = 1/resource_precision
       total_price = sum(total_price * precision) / precision

More Solution (Problem 2)

* SELECT SUM(BIGINT(quantity * 100)) / 100

  • should be quite fast and sufficient in most cases

More Solution (Problem 2 and part of Problem 5)

* SELECT SUM(DECIMAL(quantity, 30))

  • should be really precise

More Solution (Problem 1)

* Include rounding in any value related to accounting (ex. total price in invoice or proforma)

  • (ex. VAT value, salary values)

More Solution (Problem 3)

* Add a line to accounting to store the difference in a special account

  • round(a) + round(b) - round(a + b)

More Solution

* Implement arithmetics on amounts directly. (on the class)

Another problem: delivery_error in the simulation

delivery_error is a property on simulation movements for rounding problems:

simulation.quantity + simulation.delivery_error = simulation.delivery_ratio * delivery.quantity


A solver which solve quantity divergence is able and must update the error value for the quantity divergence it solves.


IMHO in solver one shall/may set delivery_error as:

simulation_movement.edit(delivery_error = simulation_movement.getDeliveryRatio() * quantity_collected_on_input - simulation_movement.getCorrectedQuantity())

Correct me if I'm wrong.ŁukaszNowak


Discussion/FloatRounding (last edited 2008-03-06 09:55:20 by ŁukaszNowak)

Page
  • Immutable Page
  • Info
  • Attachments
User
Learn about new ERP5 releases,technical articles, events and more.

Subscribe to the monthly ERP5 Newsletter!