gmpy
gmpy copied to clipboard
Expected behavior of math.ceil, math.floor, math.trunc, and round
Note: I am specifically discussing float/mpfr inputs.
The behavior of the math.ceil
, math.floor
, math.trunc
, and round
changed between Python 2 and Python 3. In Python 2.x, a float was always returned. In Python 3.x, math.ceil
, math.floor
, and math.trunc
return an integer type instead of a floating point type. round
returns an integer type if the requested numbers of digits is 0 but returns a floating point type for in the requested number of digits is either greater than 0 or less than 0.
What should gmpy2 2.1 do?
- Follow the behavior of the Python version?
- Continue to use the Python 2 behavior even in Python 3?
- Use the Python 3 behavior on Python 2?
- Add a context option to allow the user to select a specific behavior?
I would like to propose another alternative that sounds more consistent to what gmpy2 is.
- implement
floor
,ceil
andround
as methods of mpfr objects (as specified in the mpfr library withmpfr_floor
,mpfr_ceil
andmpfr_round
) and ignore the Python behavior ofmath.ceil
,math.floor
andmath.trunc
with gmpy2 arguments.
I would like to strongly advise that gmpy2 follow the Python 3 behavior and return integer types for the built-in Python math functions. I don't see a need for gmpy2 to continue to support Python 2 at this point, but if you do, you should match the behavior of the Python version that is running (option 1), unless that makes the code too complicated in which case just use Python 3 behavior everywhere (option 3) (although if the code is too complicated, that's a good sign you should drop Python 2 support).
The @videlec suggestion to not implement math.ceil, etc. is a bad one. Not only would that break compatibility with existing code, but it breaks with the design of gmpy2 which is to have Python duck-typed numeric types that wrap GMP types. I don't really follow the argument as to how this would be more consistent with what gmpy2 is.
I would like to strongly advise that gmpy2 follow the Python 3 behavior and return integer types for the built-in Python math functions.
There are no options. The Python documentation says: "If x is not a float, delegates to x.floor, which should return an Integral value." (c) Same for __ceil__()
and __trunc__()
dunders. We have only options: mpz or int. Probably we should choose mpz.
Yes the result should definitely stay as a gmpy type as long as Python allows it.
Would this be considered a bugfix and appropriate for v2.2.2 or must it wait for v2.3.0? I personally am ok with it as a bugfix.
For me this looks as a bugfix as well. Probably, you should create a dedicated branch for 2.2.x releases.