gmpy icon indicating copy to clipboard operation
gmpy copied to clipboard

Expected behavior of math.ceil, math.floor, math.trunc, and round

Open casevh opened this issue 7 years ago • 6 comments

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?

  1. Follow the behavior of the Python version?
  2. Continue to use the Python 2 behavior even in Python 3?
  3. Use the Python 3 behavior on Python 2?
  4. Add a context option to allow the user to select a specific behavior?

casevh avatar May 29 '17 17:05 casevh

I would like to propose another alternative that sounds more consistent to what gmpy2 is.

  1. implement floor, ceil and round as methods of mpfr objects (as specified in the mpfr library with mpfr_floor, mpfr_ceil and mpfr_round) and ignore the Python behavior of math.ceil, math.floor and math.trunc with gmpy2 arguments.

videlec avatar Jun 15 '17 07:06 videlec

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.

asmeurer avatar Jun 09 '20 06:06 asmeurer

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.

skirpichev avatar Jul 22 '24 13:07 skirpichev

Yes the result should definitely stay as a gmpy type as long as Python allows it.

asmeurer avatar Jul 22 '24 20:07 asmeurer

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.

casevh avatar Jul 23 '24 00:07 casevh

For me this looks as a bugfix as well. Probably, you should create a dedicated branch for 2.2.x releases.

skirpichev avatar Jul 23 '24 03:07 skirpichev