43static inline void bc_mul_carry_calc(
BC_VECTOR *prod_vector,
size_t prod_arr_size)
45 for (
size_t i = 0; i < prod_arr_size - 1; i++) {
55static inline void bc_fast_mul(
bc_num n1,
size_t n1len,
bc_num n2,
size_t n2len,
bc_num *prod)
57 const char *n1end = n1->
n_value + n1len - 1;
58 const char *n2end = n2->
n_value + n2len - 1;
60 BC_VECTOR n1_vector = bc_partial_convert_to_vector(n1end, n1len);
61 BC_VECTOR n2_vector = bc_partial_convert_to_vector(n2end, n2len);
62 BC_VECTOR prod_vector = n1_vector * n2_vector;
64 size_t prodlen = n1len + n2len;
66 char *pptr = (*prod)->n_value;
67 char *pend = pptr + prodlen - 1;
69 while (pend >= pptr) {
70 *pend-- = prod_vector %
BASE;
79static inline void bc_fast_square(
bc_num n1,
size_t n1len,
bc_num *prod)
81 const char *n1end = n1->
n_value + n1len - 1;
83 BC_VECTOR n1_vector = bc_partial_convert_to_vector(n1end, n1len);
84 BC_VECTOR prod_vector = n1_vector * n1_vector;
86 size_t prodlen = n1len + n1len;
88 char *pptr = (*prod)->n_value;
89 char *pend = pptr + prodlen - 1;
91 while (pend >= pptr) {
92 *pend-- = prod_vector %
BASE;
99static inline void bc_mul_finish_from_vector(
BC_VECTOR *prod_vector,
size_t prod_arr_size,
size_t prodlen,
bc_num *prod) {
104 bc_mul_carry_calc(prod_vector, prod_arr_size);
108 char *pptr = (*prod)->n_value;
109 char *pend = pptr + prodlen - 1;
111 while (i < prod_arr_size - 1) {
112#if BC_VECTOR_SIZE == 4
127 while (pend >= pptr) {
128 *pend-- = prod_vector[i] %
BASE;
129 prod_vector[i] /=
BASE;
141static void bc_standard_mul(
bc_num n1,
size_t n1len,
bc_num n2,
size_t n2len,
bc_num *prod)
144 const char *n1end = n1->
n_value + n1len - 1;
145 const char *n2end = n2->
n_value + n2len - 1;
146 size_t prodlen = n1len + n2len;
161 BC_VECTOR *prod_vector = n2_vector + n2_arr_size;
163 for (i = 0; i < prod_arr_size; i++) {
168 bc_convert_to_vector(n1_vector, n1end, n1len);
169 bc_convert_to_vector(n2_vector, n2end, n2len);
173 for (i = 0; i < n1_arr_size; i++) {
180 bc_mul_carry_calc(prod_vector, prod_arr_size);
184 for (
size_t j = 0;
j < n2_arr_size;
j++) {
185 prod_vector[i +
j] += n1_vector[i] * n2_vector[
j];
189 bc_mul_finish_from_vector(prod_vector, prod_arr_size, prodlen, prod);
195static void bc_standard_square(
bc_num n1,
size_t n1len,
bc_num *prod)
198 const char *n1end = n1->
n_value + n1len - 1;
199 size_t prodlen = n1len + n1len;
207 BC_VECTOR *prod_vector = n1_vector + n1_arr_size + n1_arr_size;
209 for (i = 0; i < prod_arr_size; i++) {
214 bc_convert_to_vector(n1_vector, n1end, n1len);
218 for (i = 0; i < n1_arr_size; i++) {
225 bc_mul_carry_calc(prod_vector, prod_arr_size);
229 for (
size_t j = 0;
j < n1_arr_size;
j++) {
230 prod_vector[i +
j] += n1_vector[i] * n1_vector[
j];
234 bc_mul_finish_from_vector(prod_vector, prod_arr_size, prodlen, prod);
255 bc_fast_mul(n1, len1, n2, len2, &prod);
257 bc_standard_mul(n1, len1, n2, len2, &prod);
262 prod->
n_len -= full_scale;
277 size_t prod_scale =
MIN(full_scale,
MAX(scale, n1->
n_scale));
280 bc_fast_square(n1, len1, &prod);
282 bc_standard_square(n1, len1, &prod);
286 prod->
n_len -= full_scale;
count(Countable|array $value, int $mode=COUNT_NORMAL)
bool bc_is_zero(bc_num num)
struct bc_struct * bc_num
#define bc_new_num_nonzeroed(length, scale)
void bc_write_bcd_representation(uint32_t value, char *str)
zend_ffi_ctype_name_buf buf
void _bc_rm_leading_zeros(bc_num num)
#define BC_VECTOR_BOUNDARY_NUM
#define BC_VECTOR_NO_OVERFLOW_ADD_COUNT
bc_num bc_square(bc_num n1, size_t scale)
bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale)
#define safe_emalloc(nmemb, size, offset)
#define UNEXPECTED(condition)