summaryrefslogtreecommitdiff
path: root/openerp/tools/float_utils.py
diff options
context:
space:
mode:
authorDenis Ledoux <dle@odoo.com>2014-09-26 21:21:06 +0200
committerDenis Ledoux <dle@odoo.com>2014-09-26 21:21:06 +0200
commit333852e19dd3d5174e07e29f9d8f6c087b2c09f6 (patch)
treefd180c81bae8f0483d329bfb44474c171fb10be5 /openerp/tools/float_utils.py
parentceff8ef8992b598d44e95ed349dc63b2d6c6b5c1 (diff)
Revert "[FIX] product,float_utils: perform ceiling via float_round with new rounding_method UP"
This reverts commit d4972ffdb6b9356a524eef1dbc11f455ff4473f2. Seems to break some cases, at least in _product_reserve from stock/stock.py Actual use case: SELECT product_uom, sum(product_qty) AS product_qty FROM stock_move WHERE location_dest_id=%s AND location_id<>%s AND product_id=3645 AND state='done' GROUP BY product_uom; returning 1 | 6 SELECT product_uom,-sum(product_qty) AS product_qty FROM stock_move WHERE location_id=%s AND location_dest_id<>%s AND product_id=%s AND state in ('done', 'assigned') GROUP BY product_uom; returning 1 | -6 results += cr.dictfetchall() total = 0.0 results2 = 0.0 for r in results: amount = uom_obj._compute_qty(cr, uid, r['product_uom'], r['product_qty'], context.get('uom', False)) results2 += amount total += amount Total = 1, amount = -5 It should actually be Total = 0, amount = -6
Diffstat (limited to 'openerp/tools/float_utils.py')
-rw-r--r--openerp/tools/float_utils.py29
1 files changed, 7 insertions, 22 deletions
diff --git a/openerp/tools/float_utils.py b/openerp/tools/float_utils.py
index 79f5a34c7f6..5c934114e3c 100644
--- a/openerp/tools/float_utils.py
+++ b/openerp/tools/float_utils.py
@@ -29,11 +29,10 @@ def _float_check_precision(precision_digits=None, precision_rounding=None):
return 10 ** -precision_digits
return precision_rounding
-def float_round(value, precision_digits=None, precision_rounding=None, rounding_method='HALF-UP'):
- """Return ``value`` rounded to ``precision_digits`` decimal digits,
- minimizing IEEE-754 floating point representation errors, and applying
- the tie-breaking rule selected with ``rounding_method``, by default
- HALF-UP (away from zero).
+def float_round(value, precision_digits=None, precision_rounding=None):
+ """Return ``value`` rounded to ``precision_digits``
+ decimal digits, minimizing IEEE-754 floating point representation
+ errors, and applying HALF-UP (away from zero) tie-breaking rule.
Precision must be given by ``precision_digits`` or ``precision_rounding``,
not both!
@@ -42,9 +41,6 @@ def float_round(value, precision_digits=None, precision_rounding=None, rounding_
:param float precision_rounding: decimal number representing the minimum
non-zero value at the desired precision (for example, 0.01 for a
2-digit precision).
- :param rounding_method: the rounding method used: 'HALF-UP' or 'UP', the first
- one rounding up to the closest number with the rule that number>=0.5 is
- rounded up to 1, and the latest one always rounding up.
:return: rounded float
"""
rounding_factor = _float_check_precision(precision_digits=precision_digits,
@@ -56,7 +52,7 @@ def float_round(value, precision_digits=None, precision_rounding=None, rounding_
# we normalize the value before rounding it as an integer, and de-normalize
# after rounding: e.g. float_round(1.3, precision_rounding=.5) == 1.5
- # TIE-BREAKING: HALF-UP (for normal rounding)
+ # TIE-BREAKING: HALF-UP
# We want to apply HALF-UP tie-breaking rules, i.e. 0.5 rounds away from 0.
# Due to IEE754 float/double representation limits, the approximation of the
# real value may be slightly below the tie limit, resulting in an error of
@@ -70,19 +66,8 @@ def float_round(value, precision_digits=None, precision_rounding=None, rounding_
normalized_value = value / rounding_factor # normalize
epsilon_magnitude = math.log(abs(normalized_value), 2)
epsilon = 2**(epsilon_magnitude-53)
- if rounding_method == 'HALF-UP':
- normalized_value += cmp(normalized_value,0) * epsilon
- rounded_value = round(normalized_value) # round to integer
-
- # TIE-BREAKING: UP (for ceiling operations)
- # When rounding the value up, we instead subtract the epsilon value
- # as the the approximation of the real value may be slightly *above* the
- # tie limit, this would result in incorrectly rounding up to the next number
-
- elif rounding_method == 'UP':
- normalized_value -= cmp(normalized_value,0) * epsilon
- rounded_value = math.ceil(normalized_value) # ceil to integer
-
+ normalized_value += cmp(normalized_value,0) * epsilon
+ rounded_value = round(normalized_value) # round to integer
result = rounded_value * rounding_factor # de-normalize
return result