On Fri, 9 Oct 2020 at 23:41, Tim Peters
But the decimal spec takes a different approach, which Python's docs don't explain at all: the otherwise-mysterious ROUND_05UP rounding mode. Quoting from the spec:
http://speleotrove.com/decimal/damodel.html ... The rounding mode round-05up permits arithmetic at shorter lengths to be emulated in a fixed-precision environment without double rounding. For example, a multiplication at a precision of 9 can be effected by carrying out the multiplication at (say) 16 digits using round-05up and then rounding to the required length using the desired rounding algorithm.
In your original example, 1.01 * 1.46 rounds to 4-digit 1.474 under ROUND_05UP. and then `quantize()` can be used to round that back to 1, 2, or 3 digits under any rounding mode you like.
Or, with your last example,
with decimal.localcontext() as ctx: ... ctx.rounding = decimal.ROUND_05UP ... r = D('1.00000000000001')*D('1.49999999999996') r Decimal('1.499999999999974999999999999') r.quantize(D('.00000000000001')) Decimal('1.49999999999997')
And can't be this the default of decimal? For what I know, this is the default of BigDecimal in Java:
public BigDecimal multiply(BigDecimal multiplicand)
Returns a BigDecimal whose value is (this × multiplicand), and whose scale is (this.scale() + multiplicand.scale()). Parameters:multiplicand - value to be multiplied by this BigDecimal.Returns:this * multiplicand
public BigDecimal multiply(BigDecimal multiplicand, MathContext mc)
Returns a BigDecimal whose value is (this × multiplicand), with rounding according to the context settings.
Example online: http://tpcg.io/5axMxUQb