Branch data Line data Source code
1 : : /*
2 : : * This file is part of the MicroPython project, http://micropython.org/
3 : : *
4 : : * The MIT License (MIT)
5 : : *
6 : : * Copyright (c) 2013, 2014 Damien P. George
7 : : *
8 : : * Permission is hereby granted, free of charge, to any person obtaining a copy
9 : : * of this software and associated documentation files (the "Software"), to deal
10 : : * in the Software without restriction, including without limitation the rights
11 : : * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 : : * copies of the Software, and to permit persons to whom the Software is
13 : : * furnished to do so, subject to the following conditions:
14 : : *
15 : : * The above copyright notice and this permission notice shall be included in
16 : : * all copies or substantial portions of the Software.
17 : : *
18 : : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 : : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 : : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 : : * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 : : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 : : * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 : : * THE SOFTWARE.
25 : : */
26 : :
27 : : #include <string.h>
28 : : #include <stdio.h>
29 : : #include <assert.h>
30 : :
31 : : #include "py/parsenumbase.h"
32 : : #include "py/smallint.h"
33 : : #include "py/objint.h"
34 : : #include "py/runtime.h"
35 : :
36 : : #if MICROPY_PY_BUILTINS_FLOAT
37 : : #include <math.h>
38 : : #endif
39 : :
40 : : #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_MPZ
41 : :
42 : : #if MICROPY_PY_SYS_MAXSIZE
43 : : // Export value for sys.maxsize
44 : : // *FORMAT-OFF*
45 : : #define DIG_MASK ((MPZ_LONG_1 << MPZ_DIG_SIZE) - 1)
46 : : STATIC const mpz_dig_t maxsize_dig[] = {
47 : : #define NUM_DIG 1
48 : : (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 0) & DIG_MASK,
49 : : #if (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 0) > DIG_MASK
50 : : #undef NUM_DIG
51 : : #define NUM_DIG 2
52 : : (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 1) & DIG_MASK,
53 : : #if (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 1) > DIG_MASK
54 : : #undef NUM_DIG
55 : : #define NUM_DIG 3
56 : : (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 2) & DIG_MASK,
57 : : #if (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 2) > DIG_MASK
58 : : #undef NUM_DIG
59 : : #define NUM_DIG 4
60 : : (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 3) & DIG_MASK,
61 : : #if (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 3) > DIG_MASK
62 : : #error cannot encode MP_SSIZE_MAX as mpz
63 : : #endif
64 : : #endif
65 : : #endif
66 : : #endif
67 : : };
68 : : // *FORMAT-ON*
69 : : const mp_obj_int_t mp_sys_maxsize_obj = {
70 : : {&mp_type_int},
71 : : {.fixed_dig = 1, .len = NUM_DIG, .alloc = NUM_DIG, .dig = (mpz_dig_t *)maxsize_dig}
72 : : };
73 : : #undef DIG_MASK
74 : : #undef NUM_DIG
75 : : #endif
76 : :
77 : 32250 : mp_obj_int_t *mp_obj_int_new_mpz(void) {
78 : 32250 : mp_obj_int_t *o = mp_obj_malloc(mp_obj_int_t, &mp_type_int);
79 : 32250 : mpz_init_zero(&o->mpz);
80 : 32250 : return o;
81 : : }
82 : :
83 : : // This routine expects you to pass in a buffer and size (in *buf and buf_size).
84 : : // If, for some reason, this buffer is too small, then it will allocate a
85 : : // buffer and return the allocated buffer and size in *buf and *buf_size. It
86 : : // is the callers responsibility to free this allocated buffer.
87 : : //
88 : : // The resulting formatted string will be returned from this function and the
89 : : // formatted size will be in *fmt_size.
90 : : //
91 : : // This particular routine should only be called for the mpz representation of the int.
92 : 41082 : char *mp_obj_int_formatted_impl(char **buf, size_t *buf_size, size_t *fmt_size, mp_const_obj_t self_in,
93 : : int base, const char *prefix, char base_char, char comma) {
94 [ + - - + ]: 41082 : assert(mp_obj_is_exact_type(self_in, &mp_type_int));
95 : 41082 : const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
96 : :
97 : 41082 : size_t needed_size = mp_int_format_size(mpz_max_num_bits(&self->mpz), base, prefix, comma);
98 [ + + ]: 41082 : if (needed_size > *buf_size) {
99 : 12916 : *buf = m_new(char, needed_size);
100 : 12916 : *buf_size = needed_size;
101 : : }
102 : 41082 : char *str = *buf;
103 : :
104 : 41082 : *fmt_size = mpz_as_str_inpl(&self->mpz, base, prefix, base_char, comma, str);
105 : :
106 : 41082 : return str;
107 : : }
108 : :
109 : 16 : mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf) {
110 : 16 : mp_obj_int_t *o = mp_obj_int_new_mpz();
111 : 16 : mpz_set_from_bytes(&o->mpz, big_endian, len, buf);
112 : 16 : return MP_OBJ_FROM_PTR(o);
113 : : }
114 : :
115 : 72 : void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) {
116 [ + - - + ]: 72 : assert(mp_obj_is_exact_type(self_in, &mp_type_int));
117 : 72 : mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
118 : 72 : mpz_as_bytes(&self->mpz, big_endian, len, buf);
119 : 72 : }
120 : :
121 : 79292 : int mp_obj_int_sign(mp_obj_t self_in) {
122 [ + + ]: 79292 : if (mp_obj_is_small_int(self_in)) {
123 : 74802 : mp_int_t val = MP_OBJ_SMALL_INT_VALUE(self_in);
124 [ + + ]: 74802 : if (val < 0) {
125 : : return -1;
126 [ + + ]: 73946 : } else if (val > 0) {
127 : : return 1;
128 : : } else {
129 : 37353 : return 0;
130 : : }
131 : : }
132 : 4490 : mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
133 [ + + ]: 4490 : if (self->mpz.len == 0) {
134 : : return 0;
135 [ + + ]: 4480 : } else if (self->mpz.neg == 0) {
136 : : return 1;
137 : : } else {
138 : 2 : return -1;
139 : : }
140 : : }
141 : :
142 : 1500 : mp_obj_t mp_obj_int_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
143 : 1500 : mp_obj_int_t *o = MP_OBJ_TO_PTR(o_in);
144 [ + + + + : 1500 : switch (op) {
+ + + ]
145 : 814 : case MP_UNARY_OP_BOOL:
146 [ + + ]: 814 : return mp_obj_new_bool(!mpz_is_zero(&o->mpz));
147 : 12 : case MP_UNARY_OP_HASH:
148 : 12 : return MP_OBJ_NEW_SMALL_INT(mpz_hash(&o->mpz));
149 : : case MP_UNARY_OP_POSITIVE:
150 : : return o_in;
151 : 580 : case MP_UNARY_OP_NEGATIVE: { mp_obj_int_t *o2 = mp_obj_int_new_mpz();
152 : 580 : mpz_neg_inpl(&o2->mpz, &o->mpz);
153 : 580 : return MP_OBJ_FROM_PTR(o2);
154 : : }
155 : 72 : case MP_UNARY_OP_INVERT: { mp_obj_int_t *o2 = mp_obj_int_new_mpz();
156 : 72 : mpz_not_inpl(&o2->mpz, &o->mpz);
157 : 72 : return MP_OBJ_FROM_PTR(o2);
158 : : }
159 : 10 : case MP_UNARY_OP_ABS: {
160 : 10 : mp_obj_int_t *self = MP_OBJ_TO_PTR(o_in);
161 [ + + ]: 10 : if (self->mpz.neg == 0) {
162 : : return o_in;
163 : : }
164 : 6 : mp_obj_int_t *self2 = mp_obj_int_new_mpz();
165 : 6 : mpz_abs_inpl(&self2->mpz, &self->mpz);
166 : 6 : return MP_OBJ_FROM_PTR(self2);
167 : : }
168 : : case MP_UNARY_OP_INT_MAYBE:
169 : : return o_in;
170 : 4 : default:
171 : 4 : return MP_OBJ_NULL; // op not supported
172 : : }
173 : : }
174 : :
175 : 43559 : mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
176 : 43559 : const mpz_t *zlhs;
177 : 43559 : const mpz_t *zrhs;
178 : 43559 : mpz_t z_int;
179 : 43559 : mpz_dig_t z_int_dig[MPZ_NUM_DIG_FOR_INT];
180 : :
181 : : // lhs could be a small int (eg small-int + mpz)
182 [ + + ]: 43559 : if (mp_obj_is_small_int(lhs_in)) {
183 : 1745 : mpz_init_fixed_from_int(&z_int, z_int_dig, MPZ_NUM_DIG_FOR_INT, MP_OBJ_SMALL_INT_VALUE(lhs_in));
184 : 1745 : zlhs = &z_int;
185 : : } else {
186 [ + - - + ]: 41814 : assert(mp_obj_is_exact_type(lhs_in, &mp_type_int));
187 : 41814 : zlhs = &((mp_obj_int_t *)MP_OBJ_TO_PTR(lhs_in))->mpz;
188 : : }
189 : :
190 : : // if rhs is small int, then lhs was not (otherwise mp_binary_op handles it)
191 [ + + ]: 43559 : if (mp_obj_is_small_int(rhs_in)) {
192 : 26802 : mpz_init_fixed_from_int(&z_int, z_int_dig, MPZ_NUM_DIG_FOR_INT, MP_OBJ_SMALL_INT_VALUE(rhs_in));
193 : 26802 : zrhs = &z_int;
194 [ + + + + ]: 16757 : } else if (mp_obj_is_exact_type(rhs_in, &mp_type_int)) {
195 : 16256 : zrhs = &((mp_obj_int_t *)MP_OBJ_TO_PTR(rhs_in))->mpz;
196 : : #if MICROPY_PY_BUILTINS_FLOAT
197 [ - + - + : 501 : } else if (mp_obj_is_float(rhs_in)) {
- + - + +
+ + + ]
198 : 10 : return mp_obj_float_binary_op(op, mpz_as_float(zlhs), rhs_in);
199 : : #endif
200 : : #if MICROPY_PY_BUILTINS_COMPLEX
201 [ - + - + : 491 : } else if (mp_obj_is_type(rhs_in, &mp_type_complex)) {
- + - + +
+ + + ]
202 : 4 : return mp_obj_complex_binary_op(op, mpz_as_float(zlhs), 0, rhs_in);
203 : : #endif
204 : : } else {
205 : : // delegate to generic function to check for extra cases
206 : 487 : return mp_obj_int_binary_op_extra_cases(op, lhs_in, rhs_in);
207 : : }
208 : :
209 : : #if MICROPY_PY_BUILTINS_FLOAT
210 [ + + ]: 43058 : if (op == MP_BINARY_OP_TRUE_DIVIDE || op == MP_BINARY_OP_INPLACE_TRUE_DIVIDE) {
211 [ + + ]: 8 : if (mpz_is_zero(zrhs)) {
212 : 4 : goto zero_division_error;
213 : : }
214 : 4 : mp_float_t flhs = mpz_as_float(zlhs);
215 : 4 : mp_float_t frhs = mpz_as_float(zrhs);
216 : 4 : return mp_obj_new_float(flhs / frhs);
217 : : }
218 : : #endif
219 : :
220 [ + + ]: 43050 : if (op >= MP_BINARY_OP_INPLACE_OR && op < MP_BINARY_OP_CONTAINS) {
221 : 24614 : mp_obj_int_t *res = mp_obj_int_new_mpz();
222 : :
223 [ + + + + : 24614 : switch (op) {
+ + + + +
+ + + ]
224 : 1118 : case MP_BINARY_OP_ADD:
225 : : case MP_BINARY_OP_INPLACE_ADD:
226 : 1118 : mpz_add_inpl(&res->mpz, zlhs, zrhs);
227 : 1118 : break;
228 : 1112 : case MP_BINARY_OP_SUBTRACT:
229 : : case MP_BINARY_OP_INPLACE_SUBTRACT:
230 : 1112 : mpz_sub_inpl(&res->mpz, zlhs, zrhs);
231 : 1112 : break;
232 : 6366 : case MP_BINARY_OP_MULTIPLY:
233 : : case MP_BINARY_OP_INPLACE_MULTIPLY:
234 : 6366 : mpz_mul_inpl(&res->mpz, zlhs, zrhs);
235 : 6366 : break;
236 : : case MP_BINARY_OP_FLOOR_DIVIDE:
237 : : case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: {
238 [ + + ]: 8928 : if (mpz_is_zero(zrhs)) {
239 : 4 : zero_division_error:
240 : 16 : mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("divide by zero"));
241 : : }
242 : 8924 : mpz_t rem;
243 : 8924 : mpz_init_zero(&rem);
244 : 8924 : mpz_divmod_inpl(&res->mpz, &rem, zlhs, zrhs);
245 : 8924 : mpz_deinit(&rem);
246 : 8924 : break;
247 : : }
248 : : case MP_BINARY_OP_MODULO:
249 : : case MP_BINARY_OP_INPLACE_MODULO: {
250 [ + + ]: 496 : if (mpz_is_zero(zrhs)) {
251 : 4 : goto zero_division_error;
252 : : }
253 : 492 : mpz_t quo;
254 : 492 : mpz_init_zero(&quo);
255 : 492 : mpz_divmod_inpl(&quo, &res->mpz, zlhs, zrhs);
256 : 492 : mpz_deinit(&quo);
257 : 492 : break;
258 : : }
259 : :
260 : 1220 : case MP_BINARY_OP_AND:
261 : : case MP_BINARY_OP_INPLACE_AND:
262 : 1220 : mpz_and_inpl(&res->mpz, zlhs, zrhs);
263 : 1220 : break;
264 : 1148 : case MP_BINARY_OP_OR:
265 : : case MP_BINARY_OP_INPLACE_OR:
266 : 1148 : mpz_or_inpl(&res->mpz, zlhs, zrhs);
267 : 1148 : break;
268 : 1144 : case MP_BINARY_OP_XOR:
269 : : case MP_BINARY_OP_INPLACE_XOR:
270 : 1144 : mpz_xor_inpl(&res->mpz, zlhs, zrhs);
271 : 1144 : break;
272 : :
273 : 2662 : case MP_BINARY_OP_LSHIFT:
274 : : case MP_BINARY_OP_INPLACE_LSHIFT:
275 : : case MP_BINARY_OP_RSHIFT:
276 : : case MP_BINARY_OP_INPLACE_RSHIFT: {
277 : 2662 : mp_int_t irhs = mp_obj_int_get_checked(rhs_in);
278 [ + + ]: 2662 : if (irhs < 0) {
279 : 8 : mp_raise_ValueError(MP_ERROR_TEXT("negative shift count"));
280 : : }
281 [ + + ]: 2654 : if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_INPLACE_LSHIFT) {
282 : 1354 : mpz_shl_inpl(&res->mpz, zlhs, irhs);
283 : : } else {
284 : 1300 : mpz_shr_inpl(&res->mpz, zlhs, irhs);
285 : : }
286 : : break;
287 : : }
288 : :
289 : : case MP_BINARY_OP_POWER:
290 : : case MP_BINARY_OP_INPLACE_POWER:
291 [ + + ]: 388 : if (mpz_is_neg(zrhs)) {
292 : : #if MICROPY_PY_BUILTINS_FLOAT
293 : 8 : return mp_obj_float_binary_op(op, mpz_as_float(zlhs), rhs_in);
294 : : #else
295 : : mp_raise_ValueError(MP_ERROR_TEXT("negative power with no float support"));
296 : : #endif
297 : : }
298 : 380 : mpz_pow_inpl(&res->mpz, zlhs, zrhs);
299 : 380 : break;
300 : :
301 : : case MP_BINARY_OP_DIVMOD: {
302 [ + + ]: 20 : if (mpz_is_zero(zrhs)) {
303 : 4 : goto zero_division_error;
304 : : }
305 : 16 : mp_obj_int_t *quo = mp_obj_int_new_mpz();
306 : 16 : mpz_divmod_inpl(&quo->mpz, &res->mpz, zlhs, zrhs);
307 : 16 : mp_obj_t tuple[2] = {MP_OBJ_FROM_PTR(quo), MP_OBJ_FROM_PTR(res)};
308 : 16 : return mp_obj_new_tuple(2, tuple);
309 : : }
310 : :
311 : : default:
312 : : return MP_OBJ_NULL; // op not supported
313 : : }
314 : :
315 : 24558 : return MP_OBJ_FROM_PTR(res);
316 : :
317 : : } else {
318 : 18436 : int cmp = mpz_cmp(zlhs, zrhs);
319 [ + + + + : 18436 : switch (op) {
+ + ]
320 : 186 : case MP_BINARY_OP_LESS:
321 [ + + ]: 290 : return mp_obj_new_bool(cmp < 0);
322 : 7168 : case MP_BINARY_OP_MORE:
323 [ + + ]: 7268 : return mp_obj_new_bool(cmp > 0);
324 : 164 : case MP_BINARY_OP_LESS_EQUAL:
325 [ + + ]: 240 : return mp_obj_new_bool(cmp <= 0);
326 : 160 : case MP_BINARY_OP_MORE_EQUAL:
327 [ + + ]: 232 : return mp_obj_new_bool(cmp >= 0);
328 : 10742 : case MP_BINARY_OP_EQUAL:
329 [ + + ]: 20258 : return mp_obj_new_bool(cmp == 0);
330 : :
331 : : default:
332 : : return MP_OBJ_NULL; // op not supported
333 : : }
334 : : }
335 : : }
336 : :
337 : : #if MICROPY_PY_BUILTINS_POW3
338 : 144 : STATIC mpz_t *mp_mpz_for_int(mp_obj_t arg, mpz_t *temp) {
339 [ + + ]: 144 : if (mp_obj_is_small_int(arg)) {
340 : 96 : mpz_init_from_int(temp, MP_OBJ_SMALL_INT_VALUE(arg));
341 : 96 : return temp;
342 : : } else {
343 : 48 : mp_obj_int_t *arp_p = MP_OBJ_TO_PTR(arg);
344 : 48 : return &(arp_p->mpz);
345 : : }
346 : : }
347 : :
348 : 60 : mp_obj_t mp_obj_int_pow3(mp_obj_t base, mp_obj_t exponent, mp_obj_t modulus) {
349 [ + + + + : 60 : if (!mp_obj_is_int(base) || !mp_obj_is_int(exponent) || !mp_obj_is_int(modulus)) {
+ - + + +
+ + - + +
+ + - + ]
350 : 12 : mp_raise_TypeError(MP_ERROR_TEXT("pow() with 3 arguments requires integers"));
351 : : } else {
352 : 48 : mp_obj_t result = mp_obj_new_int_from_ull(0); // Use the _from_ull version as this forces an mpz int
353 : 48 : mp_obj_int_t *res_p = (mp_obj_int_t *)MP_OBJ_TO_PTR(result);
354 : :
355 : 48 : mpz_t l_temp, r_temp, m_temp;
356 : 48 : mpz_t *lhs = mp_mpz_for_int(base, &l_temp);
357 : 48 : mpz_t *rhs = mp_mpz_for_int(exponent, &r_temp);
358 : 48 : mpz_t *mod = mp_mpz_for_int(modulus, &m_temp);
359 : :
360 : 48 : mpz_pow3_inpl(&(res_p->mpz), lhs, rhs, mod);
361 : :
362 [ + + ]: 48 : if (lhs == &l_temp) {
363 : 36 : mpz_deinit(lhs);
364 : : }
365 [ + + ]: 48 : if (rhs == &r_temp) {
366 : 32 : mpz_deinit(rhs);
367 : : }
368 [ + + ]: 48 : if (mod == &m_temp) {
369 : 28 : mpz_deinit(mod);
370 : : }
371 : 48 : return result;
372 : : }
373 : : }
374 : : #endif
375 : :
376 : 133688 : mp_obj_t mp_obj_new_int(mp_int_t value) {
377 [ + + ]: 133688 : if (MP_SMALL_INT_FITS(value)) {
378 : 133684 : return MP_OBJ_NEW_SMALL_INT(value);
379 : : }
380 : 4 : return mp_obj_new_int_from_ll(value);
381 : : }
382 : :
383 : 1419 : mp_obj_t mp_obj_new_int_from_ll(long long val) {
384 : 1419 : mp_obj_int_t *o = mp_obj_int_new_mpz();
385 : 1419 : mpz_set_from_ll(&o->mpz, val, true);
386 : 1419 : return MP_OBJ_FROM_PTR(o);
387 : : }
388 : :
389 : 166 : mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) {
390 : 166 : mp_obj_int_t *o = mp_obj_int_new_mpz();
391 : 166 : mpz_set_from_ll(&o->mpz, val, false);
392 : 166 : return MP_OBJ_FROM_PTR(o);
393 : : }
394 : :
395 : 2703 : mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) {
396 : : // SMALL_INT accepts only signed numbers, so make sure the input
397 : : // value fits completely in the small-int positive range.
398 [ + + ]: 2703 : if ((value & ~MP_SMALL_INT_POSITIVE_MASK) == 0) {
399 : 2643 : return MP_OBJ_NEW_SMALL_INT(value);
400 : : }
401 : 60 : return mp_obj_new_int_from_ull(value);
402 : : }
403 : :
404 : 905 : mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base) {
405 : 905 : mp_obj_int_t *o = mp_obj_int_new_mpz();
406 : 905 : size_t n = mpz_set_from_str(&o->mpz, *str, len, neg, base);
407 : 905 : *str += n;
408 : 905 : return MP_OBJ_FROM_PTR(o);
409 : : }
410 : :
411 : 1788 : mp_int_t mp_obj_int_get_truncated(mp_const_obj_t self_in) {
412 [ + + ]: 1788 : if (mp_obj_is_small_int(self_in)) {
413 : 1784 : return MP_OBJ_SMALL_INT_VALUE(self_in);
414 : : } else {
415 : 4 : const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
416 : : // hash returns actual int value if it fits in mp_int_t
417 : 4 : return mpz_hash(&self->mpz);
418 : : }
419 : : }
420 : :
421 : 2684 : mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) {
422 [ + + ]: 2684 : if (mp_obj_is_small_int(self_in)) {
423 : 2662 : return MP_OBJ_SMALL_INT_VALUE(self_in);
424 : : } else {
425 : 22 : const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
426 : 22 : mp_int_t value;
427 [ + + ]: 22 : if (mpz_as_int_checked(&self->mpz, &value)) {
428 : 18 : return value;
429 : : } else {
430 : : // overflow
431 : 4 : mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("overflow converting long int to machine word"));
432 : : }
433 : : }
434 : : }
435 : :
436 : 8 : mp_uint_t mp_obj_int_get_uint_checked(mp_const_obj_t self_in) {
437 [ + + ]: 8 : if (mp_obj_is_small_int(self_in)) {
438 [ + + ]: 4 : if (MP_OBJ_SMALL_INT_VALUE(self_in) >= 0) {
439 : 2 : return MP_OBJ_SMALL_INT_VALUE(self_in);
440 : : }
441 : : } else {
442 : 4 : const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
443 : 4 : mp_uint_t value;
444 [ + + ]: 4 : if (mpz_as_uint_checked(&self->mpz, &value)) {
445 : 2 : return value;
446 : : }
447 : : }
448 : :
449 : 4 : mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("overflow converting long int to machine word"));
450 : : }
451 : :
452 : : #if MICROPY_PY_BUILTINS_FLOAT
453 : 21624 : mp_float_t mp_obj_int_as_float_impl(mp_obj_t self_in) {
454 [ + - - + ]: 21624 : assert(mp_obj_is_exact_type(self_in, &mp_type_int));
455 : 21624 : mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
456 : 21624 : return mpz_as_float(&self->mpz);
457 : : }
458 : : #endif
459 : :
460 : : #endif
|