Skip to content

An integer rate truncates fv to an integer and makes ipmt/ppmt raise #166

Open

Description

@ArtJack

Describe the issue:

With rate given as an integer — the natural way to write a 0% loan — fv returns a truncated integer, and ipmt / ppmt raise ValueError. With rate=0.0 everything is right.

Where: in fv, fv_array = np.empty_like(rate) sizes and types the output buffer from rate alone, so an integer rate gives an int64 buffer and every float result written into it is truncated toward zero (the line dates from 8c7e6e1, 2019). ipmt builds its remaining-balance buffer through fv (_rbl), inherits the int64 dtype, and _value_like then tries to store NaN in it, which raises even when no element needs the NaN.

Expected: the output dtype follows all the inputs, e.g. np.result_type(rate, nper, pmt, pv, 1.0), so an integer rate behaves like a float one. With that one change fv gives 2206.25, ipmt -0.0 and ppmt -100.0 below, and the 110 tests still pass. None of the existing tests catches this: they all pass a float rate.

Reproduce the code example:

import numpy_financial as npf

print(npf.fv(0, 12, -100.5, -1000.25))    # 2206      expected 2206.25 = -(pv + pmt*nper) at rate 0
print(npf.fv(0.0, 12, -100.5, -1000.25))  # 2206.25
print(npf.ipmt(0, 1, 12, 1200))           # ValueError, expected 0.0 (no interest at 0%)
print(npf.ppmt(0, 1, 12, 1200))           # ValueError, expected -100.0

Error message:

Traceback (most recent call last):
  ...
  File ".../numpy_financial/_financial.py", in ipmt
ValueError: cannot convert float NaN to integer

Runtime information:

Python 3.13.13, numpy 2.5.4, numpy-financial 1.2.0.dev0 at 90e1ed1 (editable build), macOS 27.0.1 arm64.

Context for the issue:

Found by Verdict, an AI QA agent (Claude Opus); I re-ran it by hand on a fresh clone with the snippet above. The same pass flagged irr returning -1.0 instead of nan for cash flows with no sign change that end in zeros (irr([100, 50, 0]), even with raise_exceptions=True); I can file that separately if useful. It also hit the rate results below -100% that #158 fixes.

Activity

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