1 /* 2 +----------------------------------------------------------------------+ 3 | Copyright (c) The PHP Group | 4 +----------------------------------------------------------------------+ 5 | This source file is subject to version 3.01 of the PHP license, | 6 | that is bundled with this package in the file LICENSE, and is | 7 | available through the world-wide-web at the following url: | 8 | https://www.php.net/license/3_01.txt | 9 | If you did not receive a copy of the PHP license and are unable to | 10 | obtain it through the world-wide-web, please send a note to | 11 | license@php.net so we can mail you a copy immediately. | 12 +----------------------------------------------------------------------+ 13 | Authors: Saki Takamachi <saki@php.net> | 14 +----------------------------------------------------------------------+ 15 */ 16 17 #include "bcmath.h" 18 #include <stdbool.h> 19 #include "convert.h" 20 21 #define BC_LONG_MAX_DIGITS (sizeof(LONG_MIN_DIGITS) - 1) 22 bc_long2num(zend_long lval)23bc_num bc_long2num(zend_long lval) 24 { 25 bc_num num; 26 27 if (UNEXPECTED(lval == 0)) { 28 num = bc_copy_num(BCG(_zero_)); 29 return num; 30 } 31 32 bool negative = lval < 0; 33 if (UNEXPECTED(lval == ZEND_LONG_MIN)) { 34 num = bc_new_num_nonzeroed(BC_LONG_MAX_DIGITS, 0); 35 const char *ptr = LONG_MIN_DIGITS; 36 bc_copy_and_toggle_bcd(num->n_value, ptr, ptr + BC_LONG_MAX_DIGITS); 37 num->n_sign = MINUS; 38 return num; 39 } else if (negative) { 40 lval = -lval; 41 } 42 43 zend_long tmp = lval; 44 size_t len = 0; 45 while (tmp > 0) { 46 tmp /= BASE; 47 len++; 48 } 49 50 num = bc_new_num_nonzeroed(len, 0); 51 char *ptr = num->n_value + len - 1; 52 for (; len > 0; len--) { 53 *ptr-- = lval % BASE; 54 lval /= BASE; 55 } 56 num->n_sign = negative ? MINUS : PLUS; 57 58 return num; 59 } 60