* TODO: currently a hack that converts the long through a string. This is * correct, but slow. * * Another approach would be to do this numerically, in a similar way to * PyLong_AsDouble. * However, in order to respect rounding modes correctly, this needs to know * the size of the mantissa, which is platform-dependent. */
| 121 | * the size of the mantissa, which is platform-dependent. |
| 122 | */ |
| 123 | NPY_VISIBILITY_HIDDEN npy_longdouble |
| 124 | npy_longdouble_from_PyLong(PyObject *long_obj) { |
| 125 | npy_longdouble result = 1234; |
| 126 | char *end; |
| 127 | char *cstr; |
| 128 | PyObject *bytes; |
| 129 | |
| 130 | /* convert the long to a string */ |
| 131 | bytes = _PyLong_Bytes(long_obj); |
| 132 | if (bytes == NULL) { |
| 133 | return -1; |
| 134 | } |
| 135 | |
| 136 | cstr = PyBytes_AsString(bytes); |
| 137 | if (cstr == NULL) { |
| 138 | goto fail; |
| 139 | } |
| 140 | end = NULL; |
| 141 | |
| 142 | /* convert the string to a long double and capture errors */ |
| 143 | errno = 0; |
| 144 | result = NumPyOS_ascii_strtold(cstr, &end); |
| 145 | if (errno == ERANGE) { |
| 146 | /* strtold returns INFINITY of the correct sign. */ |
| 147 | if (PyErr_Warn(PyExc_RuntimeWarning, |
| 148 | "overflow encountered in conversion from python long") < 0) { |
| 149 | goto fail; |
| 150 | } |
| 151 | } |
| 152 | else if (errno) { |
| 153 | PyErr_Format(PyExc_RuntimeError, |
| 154 | "Could not parse python long as longdouble: %s (%s)", |
| 155 | cstr, |
| 156 | strerror(errno)); |
| 157 | goto fail; |
| 158 | } |
| 159 | |
| 160 | /* Extra characters at the end of the string, or nothing parsed */ |
| 161 | if (end == cstr || *end != '\0') { |
| 162 | PyErr_Format(PyExc_RuntimeError, |
| 163 | "Could not parse long as longdouble: %s", |
| 164 | cstr); |
| 165 | goto fail; |
| 166 | } |
| 167 | |
| 168 | /* finally safe to decref now that we're done with `end` */ |
| 169 | Py_DECREF(bytes); |
| 170 | return result; |
| 171 | |
| 172 | fail: |
| 173 | Py_DECREF(bytes); |
| 174 | return -1; |
| 175 | } |
nothing calls this directly
no test coverage detected