Coder Social home page Coder Social logo

Comments (8)

oscarbenjamin avatar oscarbenjamin commented on July 17, 2024 2

If we make math.log supporting types with __index__, we should do this in other functions too. The simplest way is to make PyFloat_AsDouble() using nb_index as a fallback if nb_float is not provided.

I'm not sure about this. PyFloat_AsDouble needs to return a double so there is no advantage in trying __index__ over __float__. I think it is better for types to provide __float__ if that is what they want. Any type that already defines __index__ can easily define __float__ if desired.

The problem for math.log(gmpy2.mpz(...)) is that the calculation is more accurate/complete for an integer rather than a float. In particular __index__ needs to be given a separate codepath rather than being used as a fallback in float conversion. For functions that actually want to handle integers and floats separately it is more useful if PyFloat_AsDouble does not convert integers into floats. Then PyNumber_Index can be tried as a fallback with an integer handling codepath.

from cpython.

mdickinson avatar mdickinson commented on July 17, 2024

Probably better to describe this as a feature request rather than a bug: there's never been any intention to support things other than int, and if this were implemented it wouldn't be something that should be backported to older Python versions.

That said, math.log does seem to be an outlier here; almost everything else in mathmodule.c that does explicit integer-handling does use PyNumber_Index.

from cpython.

serhiy-storchaka avatar serhiy-storchaka commented on July 17, 2024

There are several large groups of function in math: these which work with real numbers and convert arguments to C double using PyFloat_AsDouble(), these which work with integer numbers and use PyNumber_Index(), and these which call a special method (like __ceil__). math.log is an outlier because it works with real numbers, but has also a special case for integers to support values larger than the maximal Python float.

If we make math.log supporting types with __index__, we should do this in other functions too. The simplest way is to make PyFloat_AsDouble() using nb_index as a fallback if nb_float is not provided. The float() constructor does this.

from cpython.

mdickinson avatar mdickinson commented on July 17, 2024

@serhiy-storchaka

The simplest way is to make PyFloat_AsDouble() using nb_index as a fallback if nb_float is not provided.

I'm confused. Doesn't it do that already?

>>> class A:
...     def __index__(self): return 13
... 
>>> from math import cos
>>> cos(A())
0.9074467814501962

from cpython.

serhiy-storchaka avatar serhiy-storchaka commented on July 17, 2024

Oh, I overlooked this.

Then this issue is more like a bug.

>>> import math
>>> math.log10(10**1000)
1000.0
>>> class A:
...     def __index__(self): return 10**1000
...     
>>> 
>>> math.log10(A())
Traceback (most recent call last):
  File "<python-input-6>", line 1, in <module>
    math.log10(A())
    ~~~~~~~~~~^^^^^
OverflowError: int too large to convert to float

from cpython.

mdickinson avatar mdickinson commented on July 17, 2024

Then this issue is more like a bug.

True - it's definitely inconsistent that math.log works for arbitrarily large ints and for small integer-likes, but not for large integer-likes. I'm still not convinced that we would want to backport a change to 3.12 and 3.13, though.

from cpython.

serhiy-storchaka avatar serhiy-storchaka commented on July 17, 2024

#121011 is a simple solution for this inconsistency. It is not optimal for large int-like argument, because some work is done twice. Making it more efficient in this corner case needs inlining PyFloat_AsDouble and math_1. I am not sure that it is worth it.

There are other functions in the math for which we can compute a finite result for large integer argument instead of raising an OverflowError: acosh, asinh, atan, atan2, cbrt, copysign, erf, erfc, log1p, sqrt, tanh. cmath.log doesn't have a special case for large int. If we go this way, it is a long way.

from cpython.

mdickinson avatar mdickinson commented on July 17, 2024

If we go this way, it is a long way.

Agreed; I don't think we want to go this way at all. If the large int support for math.log weren't already there, I don't think there'd be a strong case for adding it. IIUC, many of the originally-intended use-cases would now be covered by something like int.bit_length.

from cpython.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.