Skip to content

BUG: integer power overflow in fv, pv and pmt #173

Open

Description

@milliondreamsblog

Describe the issue:

With integer rate and nper, fv, pv and pmt can overflow while computing (1 + rate) ** nper. Changing only rate from 1 to 1.0 gives the expected results in the examples below.

This is related to #166. I checked the source at PR #170's head (27ab9b4): it fixes the three examples in #166, but these still fail. Its change gives fv a floating output buffer; the power is still evaluated with integer arithmetic. pv and pmt are affected too.

Reproduce the code example:

import numpy_financial as npf

for rate in (1, 1.0):
    print(f"rate={rate!r}")
    print("fv: ", float(npf.fv(rate, 64, 0, -2.0**-64)))
    print("pv: ", float(npf.pv(rate, 64, -1, 0)))
    print("pmt:", float(npf.pmt(rate, 64, 1)))

Output on 1.1.0, current main, and PR #170's head:

rate=1
fv:  0.0
pv:  -inf
pmt: -0.0
rate=1.0
fv:  1.0
pv:  1.0
pmt: -1.0

Both calls should give the floating-rate results, within rounding. The exact FV is 2**-64 * 2**64 = 1, so the final result fits even in an integer output buffer. The exact PV is 1 - 2**-64, and PMT is -1 / (1 - 2**-64); both round to the values above in float64. I also checked these against Python's fractions.Fraction arithmetic.

Here 1 and 1.0 both mean 100% per period. The high rate and 64 periods are deliberate: they make the integer overflow easy to reproduce while keeping the expected outputs finite and small.

Error message:

The integer-rate pv call emits:

RuntimeWarning: divide by zero encountered in scalar divide

The fv and pmt calls return the wrong values without a warning.

Runtime information:

Checked on 30 October 2026 with Python 3.13.5, NumPy 2.5.3 and numpy-financial 1.1.0 on 64-bit Windows 11. NumPy's default integer dtype is int64.

I also ran the examples using the unmodified _financial.py from:

Those were focused source-module checks in the same environment, not full package builds or full test-suite runs.

Context for the issue:

In this environment, NumPy evaluates the intermediate 2**64 as an int64 and wraps it to zero. Promoting the output buffer cannot recover that value. Could the power calculation use a suitable promoted dtype before exponentiation, while preserving the existing Decimal support?

Using a floating-point rate avoids the problem in these examples.

Activity

  1. AtharvRG commented on Oct 31, 2026

    @AtharvRG

    I'd like to pick this up. With integer rate and nper, (1 + rate) ** nper promotes to a Python int that overflows the C long inside the financial functions. My plan: force float promotion of rate/nper at the entry of fv, pv, and pmt (e.g. np.asarray(rate, dtype=float) or an equivalent minimal conversion) so the power computation happens in floating point regardless of input dtype, and add tests with integer inputs asserting the same results as float inputs. I see #166 tracks the related truncation bug and #170 is an open PR on that side — I'll keep this fix independent and consistent with whatever lands there.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions