Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python 3 - rounding a Decimal with negative ndigits results in Decimal with scientific notation

I noticed a strange behaviour when using the round() function with a negative rounding factor (the parameter ndigits) and with the decimal module.

I'm using Python 3 (specifically 3.6.3, but I don't know if the specific minor version matters for this case).

With float it looks normal:

>>> round(10000 / 3, 2)
3333.33
>>> round(10000 / 3, 1)
3333.3
>>> round(10000 / 3, 0)
3333.0
>>> round(10000 / 3, -1)
3330.0
>>> round(10000 / 3, -2)
3300.0

With Decimal the result is correct, but it changes to scientific notation when using a negative rounding factor:

>>> from decimal import Decimal
>>> round(Decimal('10000') / 3, 2)
Decimal('3333.33')
>>> round(Decimal('10000') / 3, 1)
Decimal('3333.3')
>>> round(Decimal('10000') / 3, 0)
Decimal('3333')
>>> round(Decimal('10000') / 3, -1)
Decimal('3.33E+3')
>>> round(Decimal('10000') / 3, -2)
Decimal('3.3E+3')

My quick fix was to add 0 to the result, which restores the notation back to "normal" (non-scientific):

>>> round(Decimal('10000') / 3, -1) + 0
Decimal('3330')
>>> round(Decimal('10000') / 3, -2) + 0
Decimal('3300')

I don't think this classifies as a bug, because only the notation and not the actual value is affected, but it is strange to me nonetheless.

Does anyone have an idea why I am seeing this behaviour? Do you know if it is intended or a minor bug?

like image 611
Ralf Avatar asked Mar 06 '23 12:03

Ralf


1 Answers

This is normal and intended. Decimal tracks significant digits, and the Decimal repr is intended to preserve significant digits. Decimal('3.3E+3') has two significant digits, while Decimal('3300') has four.

like image 168
user2357112 supports Monica Avatar answered May 03 '23 11:05

user2357112 supports Monica