Should I care what -3.14 // inf produces?
Is an implementation of Python free to make up its own answers to division and modulus operatons in the case of inf and nan arguments? The standard library documentation says only that // is "rounded towards minus infinity". The language reference says that ||: 1. |x == (x//y)*y + (x%y)|, 2. the modulus has the same sign as y, and 3. division by (either kind of) zero raises |ZeroDivisionError| . It's consistent, but it doesn't define the operator over the full range of potential arguments. In Python 3.8 and 3.9:
from decimal import Decimal Decimal('-3.14') // Decimal('Infinity') Decimal('-0') -3.14 // float("inf") -1.0 import math math.floor(-3.14 / float("inf")) 0
I can see sense in all three answers, as possible interpretations of "rounded towards minus infinity", but I quite like decimal's. There seem to be no regression tests for floor division of floats, and for modulus only with finite arguments, perhaps intentionally. -- Jeff Allen
Hi Jeff, The decimal module docstring starts with: """ This is an implementation of decimal floating point arithmetic based on the General Decimal Arithmetic Specification: http://speleotrove.com/decimal/decarith.html and IEEE standard 854-1987: http://en.wikipedia.org/wiki/IEEE_854-1987 Decimal floating point has finite precision with arbitrarily large bounds. """ I suggest you to look into these standards. Victor On Thu, Sep 30, 2021 at 9:13 AM Jeff Allen <ja.py@farowl.co.uk> wrote:
Is an implementation of Python free to make up its own answers to division and modulus operatons in the case of inf and nan arguments?
The standard library documentation says only that // is "rounded towards minus infinity". The language reference says that :
x == (x//y)*y + (x%y), the modulus has the same sign as y, and division by (either kind of) zero raises ZeroDivisionError .
It's consistent, but it doesn't define the operator over the full range of potential arguments. In Python 3.8 and 3.9:
from decimal import Decimal Decimal('-3.14') // Decimal('Infinity') Decimal('-0') -3.14 // float("inf") -1.0 import math math.floor(-3.14 / float("inf")) 0
I can see sense in all three answers, as possible interpretations of "rounded towards minus infinity", but I quite like decimal's. There seem to be no regression tests for floor division of floats, and for modulus only with finite arguments, perhaps intentionally.
--
Jeff Allen
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/BXYBSUMN... Code of Conduct: http://python.org/psf/codeofconduct/
-- Night gathers, and now my watch begins. It shall not end until my death.
30.09.21 10:07, Jeff Allen пише:
from decimal import Decimal Decimal('-3.14') // Decimal('Infinity') Decimal('-0')
You do not need an infinity to see the difference.
Decimal('3.14') % Decimal('2') Decimal('1.14') Decimal('3.14') % Decimal('-2') Decimal('1.14') Decimal('-3.14') % Decimal('2') Decimal('-1.14') Decimal('-3.14') % Decimal('-2') Decimal('-1.14')
Decimals use a different rule than integers and floats: the modulus has the same sign as the dividend. It was discussed using this rule for floats (perhaps there is even FAQ or HOWTO for this), there are advantages of using it for floats (the result is more accurate). But the current rule (the modulus has the same sign as the divisor) is much much more convenient for integers, and having different rules for integers and floats is a source of bugs.
On 30/09/2021 08:57, Serhiy Storchaka wrote:
Decimals use a different rule than integers and floats: the modulus has the same sign as the dividend. It was discussed using this rule for floats (perhaps there is even FAQ or HOWTO for this), there are advantages of using it for floats (the result is more accurate). But the current rule (the modulus has the same sign as the divisor) is much much more convenient for integers, and having different rules for integers and floats is a source of bugs.
Thanks Serhiy and Victor. I hadn't realised decimal was so different from float. So decimal is not useful as a comparator. It's not an idealisation of intended float behaviour. The question is about floor-division of two Python built-in floats, involving non-finite operands, and whether this is standardised in Python the language. I couldn't find a FAQ/HOW-TO and nothing in the IEEE standard bears directly on floor division. I found an interesting discussion (https://mail.python.org/pipermail/python-dev/2007-January/070707.html) but it is having so much trouble with finite arguments that it barely mentions extended values a float might take. Tim makes good sense as always. Observing behaviour (Windows and Linux), it is consistent now but was divergent in the past. In Python 2.7.16 (Windows):
-3.14 // inf nan
In 3.8 (Windows and Linux) and 2.7 (Linux):
-3.14 // inf -1.0
I would put the change down to improving fmod conformance in MSC, rather than a Python language change. But the cause doesn't matter. The fact that both were acceptable suggests that floor division is not standardised for non-finite operands. Pragmatically, however, it is seldom a good idea to differ from CPython. A bit of extra work at run-time, to check the divsor, is not a big penalty. -- Jeff Allen
participants (3)
-
Jeff Allen
-
Serhiy Storchaka
-
Victor Stinner