Issue22306
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2014-08-30 07:58 by akima, last changed 2022-04-11 14:58 by admin. This issue is now closed.
Messages (6) | |||
---|---|---|---|
msg226125 - (view) | Author: Akima (akima) | Date: 2014-08-30 07:58 | |
1 / 0 (where both numbers are decimal.Decimal) produces a decimal.DivisionByZero exception as I would expect. This is useful. I can use a simple try except block to catch a potential division by zero error in my code. 0 / 0 (where both numbers are decimal.Decimal) produces a decimal.InvalidOperation exception. This is undesirable. I would expect another decimal.DivisionByZero exception. This means that if I want to catch a division by zero error in my code using a try except block, I now have to catch exceptions for both decimal.DivisionByZero and decimal.InvalidOperation. Presumably decimal.InvalidOperation can be raised in other scenarios, so catching it may result in masking a programming fault (which isn't just a division by zero: 0 / 0). If you perform the same division but using standard Python integers instead of decimal.Decimal objects, the behaviour is exactly as you would expect: 0 / 0 and 1 / 0 both produce a ZeroDivisionError exception. I have tested this in CPython 3.3.5, 3.2.3 and 2.7.3. All versions produce the same behaviour. Demonstration: Python 2.7.3 (default, Feb 27 2014, 19:58:35) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from decimal import Decimal as d >>> d(1) / d(0) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/decimal.py", line 1323, in __truediv__ return context._raise_error(DivisionByZero, 'x / 0', sign) File "/usr/lib/python2.7/decimal.py", line 3866, in _raise_error raise error(explanation) decimal.DivisionByZero: x / 0 >>> d(0) / d(0) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/decimal.py", line 1322, in __truediv__ return context._raise_error(DivisionUndefined, '0 / 0') File "/usr/lib/python2.7/decimal.py", line 3866, in _raise_error raise error(explanation) decimal.InvalidOperation: 0 / 0 >>> 1 / 0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: integer division or modulo by zero >>> 0 / 0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: integer division or modulo by zero >>> Here is the same demonstration but using a Python 3.2.3 interpreter: Python 3.2.3 (default, Feb 27 2014, 21:31:18) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from decimal import Decimal as d >>> d(1) / d(0) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.2/decimal.py", line 1300, in __truediv__ return context._raise_error(DivisionByZero, 'x / 0', sign) File "/usr/lib/python3.2/decimal.py", line 3926, in _raise_error raise error(explanation) decimal.DivisionByZero: x / 0 >>> d(0) / d(0) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.2/decimal.py", line 1299, in __truediv__ return context._raise_error(DivisionUndefined, '0 / 0') File "/usr/lib/python3.2/decimal.py", line 3926, in _raise_error raise error(explanation) decimal.InvalidOperation: 0 / 0 >>> 1 / 0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: division by zero >>> 0 / 0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: division by zero >>> |
|||
msg226134 - (view) | Author: Stefan Krah (skrah) * | Date: 2014-08-30 10:17 | |
The behavior is according to the specification: http://speleotrove.com/decimal/decarith.html The idea behind it is that 1/0 can be reasonably defined as infinity, whereas 0/0 is undefined. You can see that if you disable the exceptions: >>> c = getcontext() >>> c.traps[DivisionByZero] = False >>> c.traps[InvalidOperation] = False >>> >>> Decimal(1) / 0 Decimal('Infinity') >>> Decimal(0) / 0 Decimal('NaN') >>> |
|||
msg226136 - (view) | Author: Akima (akima) | Date: 2014-08-30 10:57 | |
Hi skrah. Thanks for the feedback. That specification is interesting. As this IBM spec appears to be a /general/ specification for performing decimal arithmatic and not targetted specifically at Python's decimal arithmatic implementation, I would expect all of Python to adhere to its recommendations (for consitency). If the division by 0 behaviour of the decimal module is in fact correct (as per the spec you have linked) and desirable, then perhaps the Python standard integer division by zero behaviour is incorrect. >>> 0 / 0 ... raises a ZeroDivisionError exception. This is in conflict with the IBM spec and with the behaviour of the decimal module. (I realize that arithmatic in the decimal module is not supposed to be equivalent to arithmatic with standard python number types, but this exception behaviour seems like something that should be consistent between the two arithmatic implementations.) |
|||
msg226137 - (view) | Author: Akima (akima) | Date: 2014-08-30 11:06 | |
Sorry. Scratch my last comment. I see from the docs ( https://docs.python.org/3/library/decimal.html ) that the decimal module explicitly references that IBM spec. I imagine that standard python arithmatic doesn't even attempt to conform to this ibm spec. |
|||
msg226138 - (view) | Author: Stefan Krah (skrah) * | Date: 2014-08-30 11:19 | |
According to IEEE 754-2008 binary floats should use the same exceptions in this case. 7.2 Invalid operation ... e) division: division(0, 0) or division(∞, ∞) 7.3 Division by zero The divideByZero exception shall be signaled if and only if an exact infinite result is defined for an operation on finite operands. But the Python binary float implementation is a lot older than the 2008 standard. |
|||
msg226220 - (view) | Author: Raymond Hettinger (rhettinger) * | Date: 2014-09-01 08:52 | |
> Sorry. Scratch my last comment. I see from the docs > ( https://docs.python.org/3/library/decimal.html ) >vthat the decimal module explicitly references that IBM spec. > I imagine that standard python arithmatic doesn't even attempt > to conform to this ibm spec. That is exactly correct. Closing as not-a-bug. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:58:07 | admin | set | github: 66502 |
2014-09-01 08:52:44 | rhettinger | set | status: open -> closed resolution: not a bug messages: + msg226220 |
2014-08-31 15:36:45 | jcea | set | nosy:
+ jcea |
2014-08-30 11:19:28 | skrah | set | messages: + msg226138 |
2014-08-30 11:06:41 | akima | set | messages: + msg226137 |
2014-08-30 10:57:52 | akima | set | messages: + msg226136 |
2014-08-30 10:17:32 | skrah | set | messages: + msg226134 |
2014-08-30 09:50:20 | pitrou | set | nosy:
+ rhettinger, facundobatista, mark.dickinson |
2014-08-30 09:50:12 | pitrou | set | nosy:
+ skrah |
2014-08-30 08:43:23 | akima | set | components: + Library (Lib) |
2014-08-30 07:58:54 | akima | create |