Skip to content

BUG: incorrect promotion for Python integer inputs in ldexp #29182

Open

Description

@raffienficiaud

Describe the issue:

Depending on the input types, the return value of ldexp raises an overflow or returns "infinity", while the same call with python integers just works.

Reproduce the code example:

>>> import numpy as np

# this should work: note the return type should not be float16 in this case.
>>> np.ldexp(1, np.int32(16))
<stdin>:1: RuntimeWarning: overflow encountered in ldexp
np.float16(inf)

# this should work, interestingly I do not see the overflow
>>> np.ldexp(1, np.int64(16))
np.float16(inf)

# ok, this is float
>>> np.ldexp(1., np.int64(16))
np.float64(65536.0)

# this just works fine
>>> np.ldexp(1, int(16))
np.float64(65536.0)

Error message:

See above.

Python and NumPy Versions:

  • python3.10
  • numpy2.2.6, conda hash py310hefbff90_0

Runtime Environment:

>>> import numpy; numpy.show_runtime()
[{'numpy_version': '2.2.6',
  'python': '3.10.18 | packaged by conda-forge | (main, Jun  4 2025, 14:45:41) '
            '[GCC 13.3.0]',
  'uname': uname_result(system='Linux', node='odin', release='6.1.0-32-amd64', version='#1 SMP PREEMPT_DYNAMIC Debian 6.1.129-1 (2025-03-06)', machine='x86_64')},
 {'simd_extensions': {'baseline': ['SSE', 'SSE2', 'SSE3'],
                      'found': ['SSSE3',
                                'SSE41',
                                'POPCNT',
                                'SSE42',
                                'AVX',
                                'F16C',
                                'FMA3',
                                'AVX2'],
                      'not_found': ['AVX512F',
                                    'AVX512CD',
                                    'AVX512_KNL',
                                    'AVX512_KNM',
                                    'AVX512_SKX',
                                    'AVX512_CLX',
                                    'AVX512_CNL',
                                    'AVX512_ICL',
                                    'AVX512_SPR']}}]

Context for the issue:

Code that used to work with previous versions of python now breaks, with a trivial workaround.

Activity

  1. changed the title [-]BUG: incorrect overflow or infinity with ldexp[/-] [+]BUG: incorrect promotion for Python integer inputs in `ldexp`[/+] on Jun 11, 2025
  2. seberg commented on Jun 11, 2025

    @seberg
    Member

    The problem is not the overflow, it's the float16(). That is a typical issue with NumPy that it picks the lowest loop (which is just not really the right thing).
    But with NumPy 2, that got worse, in most cases we made sure that these loops do the right thing but this slipped.

    The last version even does_the "right" thing on grounds of all inputs being int. But ldexp promotion correctly only really cares about the first argument (it's actually more broken).

    Should probably add a promoter for ldexp, although for ldexp it would really make a lot of sense to just raise an error if the first argument is integral. ldexp only makes sense on float inputs really.

  3. seberg commented on Jun 11, 2025

    @seberg
    Member

    I don't think this was ever regression though. Even in NumPy 1.x the same thing shoudl have happened, so this behavior was around forever.

  4. added this to the 2.4.0 release milestone on Jun 11, 2025
  5. raffienficiaud commented on Jun 11, 2025

    @raffienficiaud
    Author

    @seberg thanks for the quick comments, for looking into this, and for precising that this is not a regression :) The same code returned the expected value for numpy<2.0 (and not cast to any numpy type), that's why I thought it was one. This is what I had for numpy 1.26.4:

    In [1]: import numpy as np
    
    In [2]: np.ldexp(1, np.int64(16))
    Out[2]: 65536.0
    
    In [3]: np.ldexp(1, np.int32(16))
    Out[3]: 65536.0
    
  6. seberg commented on Jun 12, 2025

    @seberg
    Member

    Ah, right. You should see the same with np.ldexp(1, np.array([16])) where the second arg is not 0-D. But that is probably pretty uncommon even if math.ldexp is probably often nicer if the inputs are known float scalars.

  7. mattip commented on Aug 20, 2025

    @mattip
    Member

    interestingly I do not see the overflow (warning)

    Try running python with python -Walways to continue to see the same warning twice. Otherwise python suppresses multiple warnings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions