diff --git a/Cython/Utility/arrayarray.h b/Cython/Utility/arrayarray.h
index 46c1a208618ee7efec507b530ed9b3c6846225d6..bbd0da1a0ed0c9f574f4ffb8d57021695a4dd45c 100644
--- a/Cython/Utility/arrayarray.h
+++ b/Cython/Utility/arrayarray.h
@@ -121,13 +121,15 @@ static CYTHON_INLINE int resize(arrayobject *self, Py_ssize_t n) {
 static CYTHON_INLINE int resize_smart(arrayobject *self, Py_ssize_t n) {
     void *items = (void*) self->data.ob_item;
     Py_ssize_t newsize;
-    if (n < self->allocated) {
-        if (n*4 > self->allocated) {
-            self->ob_size = n;
-            return 0;
-        }
+    if (n < self->ob_size) {
+        self->ob_size = n;
+        return 0;
+    }
+    newsize = n + (n / 2) + 1;
+    if (newsize <= self->allocated) {   /* overflow */
+        PyErr_NoMemory();
+        return -1;
     }
-    newsize = n  * 3 / 2 + 1;
     PyMem_Resize(items, char, (size_t)(newsize * self->ob_descr->itemsize));
     if (items == NULL) {
         PyErr_NoMemory();
diff --git a/tests/run/pyarray.pyx b/tests/run/pyarray.pyx
index 970e35e3b8c9627976884646b4efe44d6e4fcb37..b6b403a6eb6264602cf62a2594e1c5e0fe47cba3 100644
--- a/tests/run/pyarray.pyx
+++ b/tests/run/pyarray.pyx
@@ -105,6 +105,16 @@ def test_resize(a):
     assert len(cb) == 10
     assert cb[9] == cb[-1] == cb.data.as_floats[9] == 9
 
+def test_resize_smart(a):
+    """
+    >>> a = array.array('d', [1, 2, 3])
+    >>> test_resize_smart(a)
+    2
+    """
+    cdef array.array cb = array.copy(a)
+    array.resize_smart(cb, 2)
+    return len(cb)
+
 def test_buffer():
     """
     >>> test_buffer()