Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion numpy_financial/_financial.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,9 @@ def fv(rate, nper, pmt, pv, when: _When = 'end'):
when = _convert_when(when)
rate, nper, pmt, pv, when = np.broadcast_arrays(rate, nper, pmt, pv, when)

fv_array = np.empty_like(rate)
# An integer `rate` on its own would give an integer buffer, truncating
# the result, so take the dtype from all the inputs (gh-166).
fv_array = np.empty_like(rate, dtype=np.result_type(rate, nper, pmt, pv, 1.0))
zero = rate == 0
nonzero = ~zero

Expand Down
21 changes: 21 additions & 0 deletions numpy_financial/tests/test_financial.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,11 @@ def test_broadcast_decimal(self, when, desired):
result = npf.ppmt(*args) if when is None else npf.ppmt(*args, when)
assert_decimal_close(result, desired, tol=1e-8)

def test_gh_166(self):
# An integer rate gave an integer buffer, so storing NaN in it
# raised a ValueError.
assert_allclose(npf.ppmt(0, 1, 12, 1200), -100.0, rtol=1e-10)


class TestIpmt:
def test_float(self):
Expand Down Expand Up @@ -679,6 +684,11 @@ def test_0d_inputs(self):
# 0d array inputs should return a scalar.
assert numpy.isscalar(npf.ipmt(*args))

def test_gh_166(self):
# An integer rate gave an integer buffer, so storing NaN in it
# raised a ValueError.
assert_allclose(npf.ipmt(0, 1, 12, 1200), 0.0, rtol=1e-10)


class TestFv:
def test_float(self):
Expand Down Expand Up @@ -749,6 +759,17 @@ def test_some_rates_zero(self):
rtol=1e-10,
)

@pytest.mark.parametrize(
"args, desired",
[
((0, 12, -100.5, -1000.25), 2206.25),
(([0, 0], 12, -100.5, -1000.25), [2206.25, 2206.25]),
],
)
def test_gh_166(self, args, desired):
# An integer rate gave an integer buffer, truncating the result.
assert_allclose(npf.fv(*args), desired, rtol=1e-10)


class TestIrr:
def test_npv_irr_congruence(self):
Expand Down