Most Powerful Open Source ERP

Float Rounding

Some data about Float Rounding.
  • Last Update:2016-05-16
  • Version:001
  • Language:en

Some data about Float ROunding

Table of Contents

  • Problem
  • Solution
  • More Solution (Problem 2)
  • More Solution (Problem 2 and part of Problem 5)
  • More Solution (Problem 1)
  • More Solution (Problem 3)
  • More Solution
  • Related Articles

    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())
    

    Related Articles