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 : 25474 : mp_obj_int_t *mp_obj_int_new_mpz(void) {
78 : 25474 : mp_obj_int_t *o = mp_obj_malloc(mp_obj_int_t, &mp_type_int);
79 : 25474 : mpz_init_zero(&o->mpz);
80 : 25474 : 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 : 22670 : 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 [ + - - + ]: 22670 : assert(mp_obj_is_exact_type(self_in, &mp_type_int));
95 : 22670 : const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
96 : :
97 : 22670 : size_t needed_size = mp_int_format_size(mpz_max_num_bits(&self->mpz), base, prefix, comma);
98 [ + + ]: 22670 : if (needed_size > *buf_size) {
99 : 12940 : *buf = m_new(char, needed_size);
100 : 12940 : *buf_size = needed_size;
101 : : }
102 : 22670 : char *str = *buf;
103 : :
104 : 22670 : *fmt_size = mpz_as_str_inpl(&self->mpz, base, prefix, base_char, comma, str);
105 : :
106 : 22670 : return str;
107 : : }
108 : :
109 : 24 : mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf) {
110 : 24 : mp_obj_int_t *o = mp_obj_int_new_mpz();
111 : 24 : mpz_set_from_bytes(&o->mpz, big_endian, len, buf);
112 : 24 : return MP_OBJ_FROM_PTR(o);
113 : : }
114 : :
115 : 132 : bool mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) {
116 [ + - - + ]: 132 : assert(mp_obj_is_exact_type(self_in, &mp_type_int));
117 : 132 : mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
118 : 132 : return mpz_as_bytes(&self->mpz, big_endian, self->mpz.neg, len, buf);
119 : : }
120 : :
121 : 79538 : int mp_obj_int_sign(mp_obj_t self_in) {
122 [ + + ]: 79538 : if (mp_obj_is_small_int(self_in)) {
123 : 75026 : mp_int_t val = MP_OBJ_SMALL_INT_VALUE(self_in);
124 [ + + ]: 75026 : if (val < 0) {
125 : : return -1;
126 [ + + ]: 74170 : } else if (val > 0) {
127 : : return 1;
128 : : } else {
129 : 37359 : return 0;
130 : : }
131 : : }
132 : 4512 : mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
133 [ + + ]: 4512 : if (self->mpz.len == 0) {
134 : : return 0;
135 [ + + ]: 4508 : } else if (self->mpz.neg == 0) {
136 : : return 1;
137 : : } else {
138 : 14 : return -1;
139 : : }
140 : : }
141 : :
142 : 604 : mp_obj_t mp_obj_int_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
143 : 604 : mp_obj_int_t *o = MP_OBJ_TO_PTR(o_in);
144 [ + + + + : 604 : switch (op) {
+ + + ]
145 : 24 : case MP_UNARY_OP_BOOL:
146 [ - + ]: 24 : 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 : 534 : case MP_UNARY_OP_NEGATIVE: { mp_obj_int_t *o2 = mp_obj_int_new_mpz();
152 : 534 : mpz_neg_inpl(&o2->mpz, &o->mpz);
153 : 534 : return MP_OBJ_FROM_PTR(o2);
154 : : }
155 : 12 : case MP_UNARY_OP_INVERT: { mp_obj_int_t *o2 = mp_obj_int_new_mpz();
156 : 12 : mpz_not_inpl(&o2->mpz, &o->mpz);
157 : 12 : 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 : 34596 : mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
176 : 34596 : const mpz_t *zlhs;
177 : 34596 : const mpz_t *zrhs;
178 : 34596 : mpz_t z_int;
179 : 34596 : mpz_dig_t z_int_dig[MPZ_NUM_DIG_FOR_INT];
180 : :
181 : : // lhs could be a small int (eg small-int + mpz)
182 [ + + ]: 34596 : if (mp_obj_is_small_int(lhs_in)) {
183 : 822 : mpz_init_fixed_from_int(&z_int, z_int_dig, MPZ_NUM_DIG_FOR_INT, MP_OBJ_SMALL_INT_VALUE(lhs_in));
184 : 822 : zlhs = &z_int;
185 : : } else {
186 [ + - - + ]: 33774 : assert(mp_obj_is_exact_type(lhs_in, &mp_type_int));
187 : 33774 : 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 [ + + ]: 34596 : if (mp_obj_is_small_int(rhs_in)) {
192 : 24622 : mpz_init_fixed_from_int(&z_int, z_int_dig, MPZ_NUM_DIG_FOR_INT, MP_OBJ_SMALL_INT_VALUE(rhs_in));
193 : 24622 : zrhs = &z_int;
194 [ + + + + ]: 9974 : } else if (mp_obj_is_exact_type(rhs_in, &mp_type_int)) {
195 : 9470 : zrhs = &((mp_obj_int_t *)MP_OBJ_TO_PTR(rhs_in))->mpz;
196 : : #if MICROPY_PY_BUILTINS_FLOAT
197 [ - + - + : 504 : } else if (mp_obj_is_float(rhs_in)) {
- + - + +
+ + + ]
198 : 8 : return mp_obj_float_binary_op(op, mpz_as_float(zlhs), rhs_in);
199 : : #endif
200 : : #if MICROPY_PY_BUILTINS_COMPLEX
201 [ - + - + : 496 : } 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 : 492 : return mp_obj_int_binary_op_extra_cases(op, lhs_in, rhs_in);
207 : : }
208 : :
209 : : #if MICROPY_PY_BUILTINS_FLOAT
210 [ + + ]: 34092 : 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 [ + + ]: 34084 : if (op >= MP_BINARY_OP_INPLACE_OR && op < MP_BINARY_OP_CONTAINS) {
221 : 17850 : mp_obj_int_t *res = mp_obj_int_new_mpz();
222 : :
223 [ + + + + : 17850 : switch (op) {
+ + + + +
+ + + ]
224 : 124 : case MP_BINARY_OP_ADD:
225 : : case MP_BINARY_OP_INPLACE_ADD:
226 : 124 : mpz_add_inpl(&res->mpz, zlhs, zrhs);
227 : 124 : break;
228 : 146 : case MP_BINARY_OP_SUBTRACT:
229 : : case MP_BINARY_OP_INPLACE_SUBTRACT:
230 : 146 : mpz_sub_inpl(&res->mpz, zlhs, zrhs);
231 : 146 : break;
232 : 5386 : case MP_BINARY_OP_MULTIPLY:
233 : : case MP_BINARY_OP_INPLACE_MULTIPLY:
234 : 5386 : mpz_mul_inpl(&res->mpz, zlhs, zrhs);
235 : 5386 : break;
236 : : case MP_BINARY_OP_FLOOR_DIVIDE:
237 : : case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: {
238 [ + + ]: 8950 : 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 : 8946 : mpz_t rem;
243 : 8946 : mpz_init_zero(&rem);
244 : 8946 : mpz_divmod_inpl(&res->mpz, &rem, zlhs, zrhs);
245 : 8946 : mpz_deinit(&rem);
246 : 8946 : 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 : 232 : case MP_BINARY_OP_AND:
261 : : case MP_BINARY_OP_INPLACE_AND:
262 : 232 : mpz_and_inpl(&res->mpz, zlhs, zrhs);
263 : 232 : break;
264 : 160 : case MP_BINARY_OP_OR:
265 : : case MP_BINARY_OP_INPLACE_OR:
266 : 160 : mpz_or_inpl(&res->mpz, zlhs, zrhs);
267 : 160 : break;
268 : 156 : case MP_BINARY_OP_XOR:
269 : : case MP_BINARY_OP_INPLACE_XOR:
270 : 156 : mpz_xor_inpl(&res->mpz, zlhs, zrhs);
271 : 156 : break;
272 : :
273 : 1782 : 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 : 1782 : mp_int_t irhs = mp_obj_int_get_checked(rhs_in);
278 [ + + ]: 1782 : if (irhs < 0) {
279 : 8 : mp_raise_ValueError(MP_ERROR_TEXT("negative shift count"));
280 : : }
281 [ + + ]: 1774 : if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_INPLACE_LSHIFT) {
282 : 1298 : mpz_shl_inpl(&res->mpz, zlhs, irhs);
283 : : } else {
284 : 476 : 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 [ + + ]: 386 : if (mpz_is_neg(zrhs)) {
292 : : #if MICROPY_PY_BUILTINS_FLOAT
293 : 4 : 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 : 382 : mpz_pow_inpl(&res->mpz, zlhs, zrhs);
299 : 382 : 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 : : // Check if the result fits in a small-int, and if so just return that.
316 : 17798 : mp_int_t res_small;
317 [ + + ]: 17798 : if (mpz_as_int_checked(&res->mpz, &res_small)) {
318 [ + + ]: 808 : if (MP_SMALL_INT_FITS(res_small)) {
319 : 702 : return MP_OBJ_NEW_SMALL_INT(res_small);
320 : : }
321 : : }
322 : :
323 : : return MP_OBJ_FROM_PTR(res);
324 : :
325 : : } else {
326 : 16234 : int cmp = mpz_cmp(zlhs, zrhs);
327 [ + + + + : 16234 : switch (op) {
+ + ]
328 : 174 : case MP_BINARY_OP_LESS:
329 [ + + ]: 274 : return mp_obj_new_bool(cmp < 0);
330 : 7136 : case MP_BINARY_OP_MORE:
331 [ + + ]: 7224 : return mp_obj_new_bool(cmp > 0);
332 : 164 : case MP_BINARY_OP_LESS_EQUAL:
333 [ + + ]: 240 : return mp_obj_new_bool(cmp <= 0);
334 : 160 : case MP_BINARY_OP_MORE_EQUAL:
335 [ + + ]: 232 : return mp_obj_new_bool(cmp >= 0);
336 : 8584 : case MP_BINARY_OP_EQUAL:
337 [ + + ]: 16780 : return mp_obj_new_bool(cmp == 0);
338 : :
339 : : default:
340 : : return MP_OBJ_NULL; // op not supported
341 : : }
342 : : }
343 : : }
344 : :
345 : : #if MICROPY_PY_BUILTINS_POW3
346 : 144 : static mpz_t *mp_mpz_for_int(mp_obj_t arg, mpz_t *temp) {
347 [ + + ]: 144 : if (mp_obj_is_small_int(arg)) {
348 : 96 : mpz_init_from_int(temp, MP_OBJ_SMALL_INT_VALUE(arg));
349 : 96 : return temp;
350 : : } else {
351 : 48 : mp_obj_int_t *arp_p = MP_OBJ_TO_PTR(arg);
352 : 48 : return &(arp_p->mpz);
353 : : }
354 : : }
355 : :
356 : 60 : mp_obj_t mp_obj_int_pow3(mp_obj_t base, mp_obj_t exponent, mp_obj_t modulus) {
357 [ + + + + : 60 : if (!mp_obj_is_int(base) || !mp_obj_is_int(exponent) || !mp_obj_is_int(modulus)) {
+ - + + +
+ + - + +
+ + - + ]
358 : 12 : mp_raise_TypeError(MP_ERROR_TEXT("pow() with 3 arguments requires integers"));
359 : : } else {
360 : 48 : mp_obj_t result = mp_obj_new_int_from_ull(0); // Use the _from_ull version as this forces an mpz int
361 : 48 : mp_obj_int_t *res_p = (mp_obj_int_t *)MP_OBJ_TO_PTR(result);
362 : :
363 : 48 : mpz_t l_temp, r_temp, m_temp;
364 : 48 : mpz_t *lhs = mp_mpz_for_int(base, &l_temp);
365 : 48 : mpz_t *rhs = mp_mpz_for_int(exponent, &r_temp);
366 : 48 : mpz_t *mod = mp_mpz_for_int(modulus, &m_temp);
367 : :
368 : 48 : mpz_pow3_inpl(&(res_p->mpz), lhs, rhs, mod);
369 : :
370 [ + + ]: 48 : if (lhs == &l_temp) {
371 : 36 : mpz_deinit(lhs);
372 : : }
373 [ + + ]: 48 : if (rhs == &r_temp) {
374 : 32 : mpz_deinit(rhs);
375 : : }
376 [ + + ]: 48 : if (mod == &m_temp) {
377 : 28 : mpz_deinit(mod);
378 : : }
379 : 48 : return result;
380 : : }
381 : : }
382 : : #endif
383 : :
384 : 137728 : mp_obj_t mp_obj_new_int(mp_int_t value) {
385 [ + + ]: 137728 : if (MP_SMALL_INT_FITS(value)) {
386 : 137724 : return MP_OBJ_NEW_SMALL_INT(value);
387 : : }
388 : 4 : return mp_obj_new_int_from_ll(value);
389 : : }
390 : :
391 : 1425 : mp_obj_t mp_obj_new_int_from_ll(long long val) {
392 : 1425 : mp_obj_int_t *o = mp_obj_int_new_mpz();
393 : 1425 : mpz_set_from_ll(&o->mpz, val, true);
394 : 1425 : return MP_OBJ_FROM_PTR(o);
395 : : }
396 : :
397 : 192 : mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) {
398 : 192 : mp_obj_int_t *o = mp_obj_int_new_mpz();
399 : 192 : mpz_set_from_ll(&o->mpz, val, false);
400 : 192 : return MP_OBJ_FROM_PTR(o);
401 : : }
402 : :
403 : 2725 : mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) {
404 : : // SMALL_INT accepts only signed numbers, so make sure the input
405 : : // value fits completely in the small-int positive range.
406 [ + + ]: 2725 : if ((value & ~MP_SMALL_INT_POSITIVE_MASK) == 0) {
407 : 2665 : return MP_OBJ_NEW_SMALL_INT(value);
408 : : }
409 : 60 : return mp_obj_new_int_from_ull(value);
410 : : }
411 : :
412 : 957 : mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base) {
413 : 957 : mp_obj_int_t *o = mp_obj_int_new_mpz();
414 : 957 : size_t n = mpz_set_from_str(&o->mpz, *str, len, neg, base);
415 : 957 : *str += n;
416 : 957 : return MP_OBJ_FROM_PTR(o);
417 : : }
418 : :
419 : 1828 : mp_int_t mp_obj_int_get_truncated(mp_const_obj_t self_in) {
420 [ + + ]: 1828 : if (mp_obj_is_small_int(self_in)) {
421 : 1824 : return MP_OBJ_SMALL_INT_VALUE(self_in);
422 : : } else {
423 : 4 : const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
424 : : // hash returns actual int value if it fits in mp_int_t
425 : 4 : return mpz_hash(&self->mpz);
426 : : }
427 : : }
428 : :
429 : 1792 : mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) {
430 [ + + ]: 1792 : if (mp_obj_is_small_int(self_in)) {
431 : 1786 : return MP_OBJ_SMALL_INT_VALUE(self_in);
432 : : } else {
433 : 6 : const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
434 : 6 : mp_int_t value;
435 [ + + ]: 6 : if (mpz_as_int_checked(&self->mpz, &value)) {
436 : : // mp_obj_int_t objects should always contain a value that is a large
437 : : // integer (if the value fits in a small-int then it should have been
438 : : // converted to a small-int object), and so this code-path should never
439 : : // be taken in normal circumstances.
440 : 2 : return value;
441 : : } else {
442 : : // overflow
443 : 4 : mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("overflow converting long int to machine word"));
444 : : }
445 : : }
446 : : }
447 : :
448 : 8 : mp_uint_t mp_obj_int_get_uint_checked(mp_const_obj_t self_in) {
449 [ + + ]: 8 : if (mp_obj_is_small_int(self_in)) {
450 [ + + ]: 4 : if (MP_OBJ_SMALL_INT_VALUE(self_in) >= 0) {
451 : 2 : return MP_OBJ_SMALL_INT_VALUE(self_in);
452 : : }
453 : : } else {
454 : 4 : const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
455 : 4 : mp_uint_t value;
456 [ + + ]: 4 : if (mpz_as_uint_checked(&self->mpz, &value)) {
457 : 2 : return value;
458 : : }
459 : : }
460 : :
461 : 4 : mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("overflow converting long int to machine word"));
462 : : }
463 : :
464 : : #if MICROPY_PY_BUILTINS_FLOAT
465 : 21624 : mp_float_t mp_obj_int_as_float_impl(mp_obj_t self_in) {
466 [ + - - + ]: 21624 : assert(mp_obj_is_exact_type(self_in, &mp_type_int));
467 : 21624 : mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
468 : 21624 : return mpz_as_float(&self->mpz);
469 : : }
470 : : #endif
471 : :
472 : : #endif
|