summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgfyoung <gfyoung17@gmail.com>2017-02-22 20:44:38 -0500
committerCharles Harris <charlesr.harris@gmail.com>2017-03-04 10:49:39 -0700
commit235632b4d01163e1b6ff01ab65ba3488068fcd5f (patch)
treef6e0012129ce9c5f8f7afbc04636587807712a4d
parent542390d680d5779af1028591d1885af0ff6d25ed (diff)
downloadnumpy-235632b4d01163e1b6ff01ab65ba3488068fcd5f.tar.gz
BUG: Remove extra digit in binary_repr at limit
For negative numbers at the limit for a given number of digits, we were appending an extra digit unnecessarily. Closes gh-8670.
-rw-r--r--numpy/core/numeric.py10
-rw-r--r--numpy/core/tests/test_numeric.py12
2 files changed, 20 insertions, 2 deletions
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
index b90b0a9c9..5a8b92a4f 100644
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -2212,7 +2212,7 @@ def binary_repr(num, width=None):
designated form.
If the `width` value is insufficient, it will be ignored, and `num` will
- be returned in binary(`num` > 0) or two's complement (`num` < 0) form
+ be returned in binary (`num` > 0) or two's complement (`num` < 0) form
with its width equal to the minimum number of bits needed to represent
the number in the designated form. This behavior is deprecated and will
later raise an error.
@@ -2282,10 +2282,16 @@ def binary_repr(num, width=None):
else:
poswidth = len(bin(-num)[2:])
- twocomp = 2**(poswidth + 1) + num
+ # See gh-8679: remove extra digit
+ # for numbers at boundaries.
+ if 2**(poswidth - 1) == -num:
+ poswidth -= 1
+
+ twocomp = 2**(poswidth + 1) + num
binary = bin(twocomp)[2:]
binwidth = len(binary)
+
outwidth = max(binwidth, width)
warn_if_insufficient(width, binwidth)
return '1' * (outwidth - binwidth) + binary
diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py
index c31e9e07c..28b58e358 100644
--- a/numpy/core/tests/test_numeric.py
+++ b/numpy/core/tests/test_numeric.py
@@ -1149,6 +1149,18 @@ class TestBinaryRepr(TestCase):
assert_equal(np.binary_repr(10, width=7), '0001010')
assert_equal(np.binary_repr(-5, width=7), '1111011')
+ def test_neg_width_boundaries(self):
+ # see gh-8670
+
+ # Ensure that the example in the issue does not
+ # break before proceeding to a more thorough test.
+ assert_equal(np.binary_repr(-128, width=8), '10000000')
+
+ for width in range(1, 11):
+ num = -2**(width - 1)
+ exp = '1' + (width - 1) * '0'
+ assert_equal(np.binary_repr(num, width=width), exp)
+
class TestBaseRepr(TestCase):
def test_base3(self):