SAP Knowledge Base Article - Public

3744536 - Python round result differs from CPQ Round Tag, causing inconsistency in scripting.

Symptom

When attempting to round the value 168830.365 to 2 decimal places in scripting workbench differs when using Python's round() function, returning .36, and using TagParserQuote.ParseString(<*ROUND()*>) returns .37. 

Environment

SAP SALES CLOUD CPQ

Reproducing the Issue

  1. Open Script Workbench
  2. Execute parser_result = TagParserQuote.ParseString('<*ROUND(168830.365, 2)*>') and script_result = round(168830.365, 2)
  3. Verify that rounding result is different.

Cause

Python Behavior.

Resolution

  • In Python 2.7, the built-in round(...) function uses "round half away from zero" strategy (e.g., 0.5 always goes up). However, due to floating-point binary representation, a number like 168830.365 is stored in memory as 168830.3650000000143..., causing it to round up to .37 even when Banker's Rounding is expected
  • Python 3 (and IronPython 3 also) fixed this by implementing "Round Half to Even" (Banker's Rounding) as the native behavior for the round() function
  • For IronPython 2 users, to ensure consistent and precise financial rounding (Banker's Rounding), use the Decimal.Round method (this is possible because C# Decimal is already available in scope, x = Decimal.Round(Decimal(168830.365), 2).

See Also

Keywords

formula builder, round, rounding discrepancy, banker’s rounding, round half to even, half away from zero, ctx tag, iron python 2, decimal.round, CPQ , KBA , CEC-SAL-CPQ , Sales Cloud CPQ , How To

Product

SAP CPQ 2024