summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/__init__.pyi2
-rw-r--r--numpy/core/_add_newdocs_scalars.py29
-rw-r--r--numpy/core/src/multiarray/scalartypes.c.src31
3 files changed, 55 insertions, 7 deletions
diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi
index f398f67b7..b2c64d17c 100644
--- a/numpy/__init__.pyi
+++ b/numpy/__init__.pyi
@@ -3342,7 +3342,7 @@ class floating(inexact[_NBit1]):
__args: Union[L[0], Tuple[()], Tuple[L[0]]] = ...,
) -> float: ...
def tolist(self) -> float: ...
- def is_integer(self: float64) -> bool: ...
+ def is_integer(self) -> bool: ...
def hex(self: float64) -> str: ...
@classmethod
def fromhex(cls: Type[float64], __string: str) -> float64: ...
diff --git a/numpy/core/_add_newdocs_scalars.py b/numpy/core/_add_newdocs_scalars.py
index 602b1db6e..709a71889 100644
--- a/numpy/core/_add_newdocs_scalars.py
+++ b/numpy/core/_add_newdocs_scalars.py
@@ -205,12 +205,12 @@ add_newdoc_for_scalar_type('bytes_', ['string_'],
add_newdoc_for_scalar_type('void', [],
r"""
Either an opaque sequence of bytes, or a structure.
-
+
>>> np.void(b'abcd')
void(b'\x61\x62\x63\x64')
-
+
Structured `void` scalars can only be constructed via extraction from :ref:`structured_arrays`:
-
+
>>> arr = np.array((1, 2), dtype=[('x', np.int8), ('y', np.int8)])
>>> arr[()]
(1, 2) # looks like a tuple, but is `np.void`
@@ -226,17 +226,17 @@ add_newdoc_for_scalar_type('datetime64', [],
>>> np.datetime64(10, 'Y')
numpy.datetime64('1980')
>>> np.datetime64('1980', 'Y')
- numpy.datetime64('1980')
+ numpy.datetime64('1980')
>>> np.datetime64(10, 'D')
numpy.datetime64('1970-01-11')
-
+
See :ref:`arrays.datetime` for more information.
""")
add_newdoc_for_scalar_type('timedelta64', [],
"""
A timedelta stored as a 64-bit integer.
-
+
See :ref:`arrays.datetime` for more information.
""")
@@ -257,3 +257,20 @@ for float_name in ('half', 'single', 'double', 'longdouble'):
>>> np.{ftype}(-.25).as_integer_ratio()
(-1, 4)
""".format(ftype=float_name)))
+
+ add_newdoc('numpy.core.numerictypes', float_name, ('is_integer',
+ f"""
+ {float_name}.is_integer() -> bool
+
+ Return ``True`` if the floating point number is finite with integral
+ value, and ``False`` otherwise.
+
+ .. versionadded:: 1.22
+
+ Examples
+ --------
+ >>> np.{float_name}(-2.0).is_integer()
+ True
+ >>> np.{float_name}(3.2).is_integer()
+ False
+ """))
diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src
index 40f736125..bf22acfec 100644
--- a/numpy/core/src/multiarray/scalartypes.c.src
+++ b/numpy/core/src/multiarray/scalartypes.c.src
@@ -1908,6 +1908,34 @@ error:
}
/**end repeat**/
+/**begin repeat
+ * #name = half, float, double, longdouble#
+ * #Name = Half, Float, Double, LongDouble#
+ * #is_half = 1,0,0,0#
+ * #c = f, f, , l#
+ */
+static PyObject *
+@name@_is_integer(PyObject *self)
+{
+#if @is_half@
+ npy_double val = npy_half_to_double(PyArrayScalar_VAL(self, @Name@));
+#else
+ npy_@name@ val = PyArrayScalar_VAL(self, @Name@);
+#endif
+ PyObject *o;
+
+ if (npy_isnan(val)) {
+ Py_RETURN_FALSE;
+ }
+ if (!npy_isfinite(val)) {
+ Py_RETURN_FALSE;
+ }
+
+ o = (npy_floor@c@(val) == val) ? Py_True : Py_False;
+ Py_INCREF(o);
+ return o;
+}
+/**end repeat**/
/*
* need to fill in doc-strings for these methods on import -- copy from
@@ -2185,6 +2213,9 @@ static PyMethodDef @name@type_methods[] = {
{"as_integer_ratio",
(PyCFunction)@name@_as_integer_ratio,
METH_NOARGS, NULL},
+ {"is_integer",
+ (PyCFunction)@name@_is_integer,
+ METH_NOARGS, NULL},
{NULL, NULL, 0, NULL}
};
/**end repeat**/