📄 gmp.c
字号:
mpz_sqrt(*gmpnum_result, *gmpnum_a); ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp); }/* }}} *//* {{{ proto array gmp_sqrtrem(resource a) Square root with remainder */ZEND_FUNCTION(gmp_sqrtrem){ zval **a_arg; mpz_t *gmpnum_a, *gmpnum_result1, *gmpnum_result2; zval r; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &a_arg) == FAILURE){ WRONG_PARAM_COUNT; } FETCH_GMP_ZVAL(gmpnum_a, a_arg); if (mpz_sgn(*gmpnum_a) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Number has to be greater than or equal to 0"); RETURN_FALSE; } INIT_GMP_NUM(gmpnum_result1); INIT_GMP_NUM(gmpnum_result2); mpz_sqrtrem(*gmpnum_result1, *gmpnum_result2, *gmpnum_a); array_init(return_value); ZEND_REGISTER_RESOURCE(&r, gmpnum_result1, le_gmp); add_index_resource(return_value, 0, Z_LVAL(r)); ZEND_REGISTER_RESOURCE(&r, gmpnum_result2, le_gmp); add_index_resource(return_value, 1, Z_LVAL(r));}/* }}} *//* {{{ proto bool gmp_perfect_square(resource a) Checks if a is an exact square */ZEND_FUNCTION(gmp_perfect_square){ zval **a_arg; mpz_t *gmpnum_a; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &a_arg) == FAILURE){ WRONG_PARAM_COUNT; } FETCH_GMP_ZVAL(gmpnum_a, a_arg); RETURN_BOOL((mpz_perfect_square_p(*gmpnum_a)!=0));}/* }}} *//* {{{ proto int gmp_prob_prime(resource a[, int reps]) Checks if a is "probably prime" */ZEND_FUNCTION(gmp_prob_prime){ zval **gmpnumber_arg, **reps_arg; mpz_t *gmpnum_a; int argc, reps=10; argc = ZEND_NUM_ARGS(); if (argc < 1 || argc > 2 || zend_get_parameters_ex(argc, &gmpnumber_arg, &reps_arg) == FAILURE){ WRONG_PARAM_COUNT; } FETCH_GMP_ZVAL(gmpnum_a, gmpnumber_arg); switch (argc) { case 2: convert_to_long_ex(reps_arg); reps = Z_LVAL_PP(reps_arg); break; case 1: reps = 10; break; } RETURN_LONG(mpz_probab_prime_p(*gmpnum_a, reps));}/* }}} *//* {{{ proto resource gmp_gcd(resource a, resource b) Computes greatest common denominator (gcd) of a and b */ZEND_FUNCTION(gmp_gcd){ zval **a_arg, **b_arg; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &a_arg, &b_arg) == FAILURE){ WRONG_PARAM_COUNT; } gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_gcd, (gmp_binary_ui_op_t)mpz_gcd_ui, 1, 0 TSRMLS_CC);}/* }}} *//* {{{ proto array gmp_gcdext(resource a, resource b) Computes G, S, and T, such that AS + BT = G = `gcd' (A, B) */ZEND_FUNCTION(gmp_gcdext){ zval **a_arg, **b_arg; mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_t, *gmpnum_s, *gmpnum_g; zval r; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &a_arg, &b_arg) == FAILURE){ WRONG_PARAM_COUNT; } FETCH_GMP_ZVAL(gmpnum_a, a_arg); FETCH_GMP_ZVAL(gmpnum_b, b_arg); INIT_GMP_NUM(gmpnum_g); INIT_GMP_NUM(gmpnum_s); INIT_GMP_NUM(gmpnum_t); mpz_gcdext(*gmpnum_g, *gmpnum_s, *gmpnum_t, *gmpnum_a, *gmpnum_b); array_init(return_value); ZEND_REGISTER_RESOURCE(&r, gmpnum_g, le_gmp); add_assoc_resource(return_value, "g", Z_LVAL(r)); ZEND_REGISTER_RESOURCE(&r, gmpnum_s, le_gmp); add_assoc_resource(return_value, "s", Z_LVAL(r)); ZEND_REGISTER_RESOURCE(&r, gmpnum_t, le_gmp); add_assoc_resource(return_value, "t", Z_LVAL(r));}/* }}} *//* {{{ proto resource gmp_invert(resource a, resource b) Computes the inverse of a modulo b */ZEND_FUNCTION(gmp_invert){ zval **a_arg, **b_arg; mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_result; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &a_arg, &b_arg) == FAILURE){ WRONG_PARAM_COUNT; } FETCH_GMP_ZVAL(gmpnum_a, a_arg); FETCH_GMP_ZVAL(gmpnum_b, b_arg); INIT_GMP_NUM(gmpnum_result); if(mpz_invert(*gmpnum_result, *gmpnum_a, *gmpnum_b)) { ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp); } else { FREE_GMP_NUM(gmpnum_result); RETURN_FALSE; }}/* }}} *//* {{{ proto int gmp_jacobi(resource a, resource b) Computes Jacobi symbol */ZEND_FUNCTION(gmp_jacobi){ gmp_binary_opl(mpz_jacobi);}/* }}} *//* {{{ proto int gmp_legendre(resource a, resource b) Computes Legendre symbol */ZEND_FUNCTION(gmp_legendre){ gmp_binary_opl(mpz_legendre);}/* }}} *//* {{{ proto int gmp_cmp(resource a, resource b) Compares two numbers */ZEND_FUNCTION(gmp_cmp){ zval **a_arg, **b_arg; mpz_t *gmpnum_a, *gmpnum_b; int use_si=0, res; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &a_arg, &b_arg) == FAILURE){ WRONG_PARAM_COUNT; } FETCH_GMP_ZVAL(gmpnum_a, a_arg); if(Z_TYPE_PP(b_arg) == IS_LONG) { use_si=1; } else { FETCH_GMP_ZVAL(gmpnum_b, b_arg); } if(use_si) { res = mpz_cmp_si(*gmpnum_a, Z_LVAL_PP(b_arg)); } else { res = mpz_cmp(*gmpnum_a, *gmpnum_b); } RETURN_LONG(res);}/* }}} *//* {{{ proto int gmp_sign(resource a) Gets the sign of the number */ZEND_FUNCTION(gmp_sign){ zval **a_arg; mpz_t *gmpnum_a; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &a_arg) == FAILURE){ WRONG_PARAM_COUNT; } FETCH_GMP_ZVAL(gmpnum_a, a_arg); RETURN_LONG(mpz_sgn(*gmpnum_a));}/* }}} *//* {{{ proto resource gmp_random([int limiter]) Gets random number */ZEND_FUNCTION(gmp_random){ zval **limiter_arg; int limiter, argc; mpz_t *gmpnum_result; argc = ZEND_NUM_ARGS(); if (argc == 0) { limiter = 20; } else if (argc == 1 && zend_get_parameters_ex(1, &limiter_arg) == SUCCESS) { convert_to_long_ex(limiter_arg); limiter = Z_LVAL_PP(limiter_arg); } else { WRONG_PARAM_COUNT; } INIT_GMP_NUM(gmpnum_result); if (!GMPG(rand_initialized)) { /* Initialize */ gmp_randinit_lc_2exp_size(GMPG(rand_state), 32L); /* Seed */ gmp_randseed_ui(GMPG(rand_state), GENERATE_SEED()); GMPG(rand_initialized) = 1; } mpz_urandomb(*gmpnum_result, GMPG(rand_state), GMP_ABS (limiter) * __GMP_BITS_PER_MP_LIMB); ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp);}/* }}} *//* {{{ proto resource gmp_and(resource a, resource b) Calculates logical AND of a and b */ZEND_FUNCTION(gmp_and){ gmp_binary_op(mpz_and);}/* }}} *//* {{{ proto resource gmp_or(resource a, resource b) Calculates logical OR of a and b */ZEND_FUNCTION(gmp_or){ gmp_binary_op(mpz_ior);}/* }}} *//* {{{ proto resource gmp_com(resource a) Calculates one's complement of a */ZEND_FUNCTION(gmp_com){ gmp_unary_op(mpz_com);}/* }}} *//* {{{ proto resource gmp_xor(resource a, resource b) Calculates logical exclusive OR of a and b */ZEND_FUNCTION(gmp_xor){ /* use formula: a^b = (a|b)&^(a&b) */ zval **a_arg, **b_arg; mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_result, *gmpnum_t; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &a_arg, &b_arg) == FAILURE){ WRONG_PARAM_COUNT; } FETCH_GMP_ZVAL(gmpnum_a, a_arg); FETCH_GMP_ZVAL(gmpnum_b, b_arg); INIT_GMP_NUM(gmpnum_result); INIT_GMP_NUM(gmpnum_t); mpz_and(*gmpnum_t, *gmpnum_a, *gmpnum_b); mpz_com(*gmpnum_t, *gmpnum_t); mpz_ior(*gmpnum_result, *gmpnum_a, *gmpnum_b); mpz_and(*gmpnum_result, *gmpnum_result, *gmpnum_t); FREE_GMP_NUM(gmpnum_t); ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp);}/* }}} *//* {{{ proto void gmp_setbit(resource &a, int index[, bool set_clear]) Sets or clear bit in a */ZEND_FUNCTION(gmp_setbit){ zval **a_arg, **ind_arg, **set_c_arg; int argc, index, set=1; mpz_t *gmpnum_a; argc = ZEND_NUM_ARGS(); if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &a_arg, &ind_arg, &set_c_arg) == FAILURE){ WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(gmpnum_a, mpz_t *, a_arg, -1, GMP_RESOURCE_NAME, le_gmp); convert_to_long_ex(ind_arg); index = Z_LVAL_PP(ind_arg); switch (argc) { case 3: convert_to_long_ex(set_c_arg); set = Z_LVAL_PP(set_c_arg); break; case 2: set = 1; break; } if(set) { mpz_setbit(*gmpnum_a, index); } else { mpz_clrbit(*gmpnum_a, index); }}/* }}} *//* {{{ proto void gmp_clrbit(resource &a, int index) Clears bit in a */ZEND_FUNCTION(gmp_clrbit){ zval **a_arg, **ind_arg; int index; mpz_t *gmpnum_a; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &a_arg, &ind_arg) == FAILURE){ WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(gmpnum_a, mpz_t *, a_arg, -1, GMP_RESOURCE_NAME, le_gmp); convert_to_long_ex(ind_arg); index = Z_LVAL_PP(ind_arg); mpz_clrbit(*gmpnum_a, index);}/* }}} *//* {{{ proto int gmp_popcount(resource a) Calculates the population count of a */ZEND_FUNCTION(gmp_popcount){ zval **a_arg; mpz_t *gmpnum_a; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &a_arg) == FAILURE){ WRONG_PARAM_COUNT; } FETCH_GMP_ZVAL(gmpnum_a, a_arg); RETURN_LONG(mpz_popcount(*gmpnum_a));}/* }}} *//* {{{ proto int gmp_hamdist(resource a, resource b) Calculates hamming distance between a and b */ZEND_FUNCTION(gmp_hamdist){ zval **a_arg, **b_arg; mpz_t *gmpnum_a, *gmpnum_b; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &a_arg, &b_arg) == FAILURE){ WRONG_PARAM_COUNT; } FETCH_GMP_ZVAL(gmpnum_a, a_arg); FETCH_GMP_ZVAL(gmpnum_b, b_arg); RETURN_LONG(mpz_hamdist(*gmpnum_a, *gmpnum_b));}/* }}} *//* {{{ proto int gmp_scan0(resource a, int start) Finds first zero bit */ZEND_FUNCTION(gmp_scan0){ zval **a_arg, **start_arg; mpz_t *gmpnum_a; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &a_arg, &start_arg) == FAILURE){ WRONG_PARAM_COUNT; } FETCH_GMP_ZVAL(gmpnum_a, a_arg); convert_to_long_ex(start_arg); RETURN_LONG(mpz_scan0(*gmpnum_a, Z_LVAL_PP(start_arg)));}/* }}} *//* {{{ proto int gmp_scan1(resource a, int start) Finds first non-zero bit */ZEND_FUNCTION(gmp_scan1){ zval **a_arg, **start_arg; mpz_t *gmpnum_a; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &a_arg, &start_arg) == FAILURE){ WRONG_PARAM_COUNT; } FETCH_GMP_ZVAL(gmpnum_a, a_arg); convert_to_long_ex(start_arg); RETURN_LONG(mpz_scan1(*gmpnum_a, Z_LVAL_PP(start_arg)));}/* }}} *//* {{{ _php_gmpnum_free */static void _php_gmpnum_free(zend_rsrc_list_entry *rsrc TSRMLS_DC){ mpz_t *gmpnum = (mpz_t *)rsrc->ptr; FREE_GMP_NUM(gmpnum);}/* }}} */#endif /* HAVE_GMP *//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -