-
-
Notifications
You must be signed in to change notification settings - Fork 11.1k
BUG: Potential fix for divmod(1.0, 0.0) to raise divbyzero and return inf #16161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
64e525d
d08bdba
7f55958
8466526
a6e7629
f527a57
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,7 @@ | |
assert_, assert_equal, assert_raises, assert_raises_regex, | ||
assert_array_equal, assert_almost_equal, assert_array_almost_equal, | ||
assert_array_max_ulp, assert_allclose, assert_no_warnings, suppress_warnings, | ||
_gen_alignment_data, assert_array_almost_equal_nulp | ||
_gen_alignment_data, assert_array_almost_equal_nulp, assert_warns | ||
) | ||
|
||
def on_powerpc(): | ||
A3E2
|
@@ -293,6 +293,19 @@ def test_floor_division_signed_zero(self): | |
assert_equal(np.signbit(x//1), 0) | ||
assert_equal(np.signbit((-x)//1), 1) | ||
|
||
@pytest.mark.parametrize('dtype', np.typecodes['Float']) | ||
def test_floor_division_corner_cases(self, dtype): | ||
# test corner cases like 1.0//0.0 for errors and return vals | ||
x = np.zeros(10, dtype=dtype) | ||
y = np.ones(10, dtype=dtype) | ||
# divide by zero error check | ||
with np.errstate(divide='raise', invalid='ignore'): | ||
assert_raises(FloatingPointError, np.floor_divide, y, x) | ||
# verify 1.0//0.0 computations return inf | ||
with np.errstate(divide='ignore'): | ||
z = np.floor_divide(y, x) | ||
assert_(np.isinf(z).all()) | ||
|
||
def floor_divide_and_remainder(x, y): | ||
return (np.floor_divide(x, y), np.remainder(x, y)) | ||
|
||
|
@@ -366,6 +379,32 @@ def test_float_remainder_roundoff(self): | |
else: | ||
assert_(b > rem >= 0, msg) | ||
|
||
@pytest.mark.parametrize('dtype', np.typecodes['Float']) | ||
def test_float_remainder_errors(self, dtype): | ||
# Check valid errors raised for divmod and remainder | ||
fzero = np.array(0.0, dtype=dtype) | ||
fone = np.array(1.0, dtype=dtype) | ||
finf = np.array(np.inf, dtype=dtype) | ||
with np.errstate(invalid='raise'): | ||
assert_raises(FloatingPointError, np.remainder, fone, fzero) | ||
# since divmod is combination of both remainder and divide | ||
# ops it will set both dividebyzero and invalid flags | ||
with np.errstate(divide='raise', invalid='ignore'): | ||
assert_raises(FloatingPointError, np.divmod, fone, fzero) | ||
with np.errstate(divide='ignore', invalid='raise'): | ||
assert_raises(FloatingPointError, np.divmod, fone, fzero) | ||
with np.errstate(invalid='raise'): | ||
assert_raises(FloatingPointError, np.divmod, fzero, fzero) | ||
with np.errstate(invalid='raise'): | ||
assert_raises(FloatingPointError, np.divmod, finf, finf) | ||
|
||
def test_float_remainder_overflow(self): | ||
a = np.finfo(np.float64).tiny | ||
with np.errstate(over='ignore', invalid='ignore'): | ||
div, mod = np.divmod(4, a) | ||
np.isinf(div) | ||
assert_(mod == 0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we test that these warnings are given, or did that fail on some hardware? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we ensure the errors invalid and dividebyzero are raised for divmod in line 370 to 373. Is this what you are looking for ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I guess I meant the specific case for |
||
|
||
def test_float_remainder_corner_cases(self): | ||
# Check remainder magnitude. | ||
for dt in np.typecodes['Float']: | ||
|
@@ -379,20 +418,31 @@ def test_float_remainder_corner_cases(self): | |
# Check nans, inf | ||
with suppress_warnings() as sup: | ||
sup.filter(RuntimeWarning, "invalid value encountered in remainder") | ||
sup.filter(RuntimeWarning, "invalid value encountered in divmod") | ||
sup.filter(RuntimeWarning, "divide by zero encountered in divmod") | ||
for dt in np.typecodes['Float']: | ||
fone = np.array(1.0, dtype=dt) | ||
fzer = np.array(0.0, dtype=dt) | ||
finf = np.array(np.inf, dtype=dt) | ||
fnan = np.array(np.nan, dtype=dt) | ||
rem = np.remainder(fone, fzer) | ||
assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) | ||
div, rem = np.divmod(fone, fzer) | ||
assert_(np.isinf(div), 'dt: %s, div: %s' % (dt, rem)) | ||
assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) | ||
# MSVC 2008 returns NaN here, so disable the check. | ||
#rem = np.remainder(fone, finf) | ||
#assert_(rem == fone, 'dt: %s, rem: %s' % (dt, rem)) | ||
rem = np.remainder(fone, fnan) | ||
assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) | ||
rem = np.remainder(finf, fone) | ||
assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) | ||
div, rem = np.divmod(fzer, fzer) | ||
assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) | ||
assert_(np.isnan(div), 'dt: %s, rem: %s' % (dt, rem)) | ||
div, rem = np.divmod(finf, finf) | ||
assert_(np.isnan(div), 'dt: %s, rem: %s' % (dt, rem)) | ||
assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) | ||
|
||
|
||
class TestCbrt: | ||
|
Uh oh!
There was an error while loading. Please reload this page.