#define GMP_BIG_ENDIAN (1 << 3)
#define GMP_NATIVE_ENDIAN (1 << 4)
-#define GMP_42_OR_NEWER \
- ((__GNU_MP_VERSION >= 5) || (__GNU_MP_VERSION >= 4 && __GNU_MP_VERSION_MINOR >= 2))
+#define GMP_MAX_BASE 62
-/* The maximum base for input and output conversions is 62 from GMP 4.2
- * onwards. */
-#if GMP_42_OR_NEWER
-# define MAX_BASE 62
-#else
-# define MAX_BASE 36
-#endif
-
+ #define GMP_51_OR_NEWER \
+ ((__GNU_MP_VERSION >= 6) || (__GNU_MP_VERSION >= 5 && __GNU_MP_VERSION_MINOR >= 1))
+
#define IS_GMP(zval) \
- (Z_TYPE_P(zval) == IS_OBJECT && instanceof_function(Z_OBJCE_P(zval), gmp_ce TSRMLS_CC))
+ (Z_TYPE_P(zval) == IS_OBJECT && instanceof_function(Z_OBJCE_P(zval), gmp_ce))
+
+#define GET_GMP_OBJECT_FROM_OBJ(obj) \
+ ((gmp_object *) ((char *) (obj) - XtOffsetOf(gmp_object, std)))
+#define GET_GMP_OBJECT_FROM_ZVAL(zv) \
+ GET_GMP_OBJECT_FROM_OBJ(Z_OBJ_P(zv))
#define GET_GMP_FROM_ZVAL(zval) \
- (((gmp_object *) zend_object_store_get_object((zval) TSRMLS_CC))->num)
+ GET_GMP_OBJECT_FROM_OBJ(Z_OBJ_P(zval))->num
/* The FETCH_GMP_ZVAL_* family of macros is used to fetch a gmp number
* (mpz_ptr) from a zval. If the zval is not a GMP instance, then we
RETURN_FALSE;
}
+ gmp_create(&result1, &gmpnum_result1);
+ gmp_create(&result2, &gmpnum_result2);
+
array_init(return_value);
- add_index_zval(return_value, 0, gmp_create(&gmpnum_result1 TSRMLS_CC));
- add_index_zval(return_value, 1, gmp_create(&gmpnum_result2 TSRMLS_CC));
+ add_next_index_zval(return_value, &result1);
+ add_next_index_zval(return_value, &result2);
- mpz_rootrem(gmpnum_result1, gmpnum_result2, gmpnum_a, (unsigned long) nth);
+ #if GMP_51_OR_NEWER
+ /* mpz_rootrem() is supported since GMP 4.2, but buggy wrt odd roots
+ * of negative numbers */
- mpz_root(gmpnum_result1, gmpnum_a, (unsigned long) nth);
- mpz_pow_ui(gmpnum_result2, gmpnum_result1, (unsigned long) nth);
+ mpz_rootrem(gmpnum_result1, gmpnum_result2, gmpnum_a, (gmp_ulong) nth);
+ #else
++ mpz_root(gmpnum_result1, gmpnum_a, (gmp_ulong) nth);
++ mpz_pow_ui(gmpnum_result2, gmpnum_result1, (gmp_ulong) nth);
+ mpz_sub(gmpnum_result2, gmpnum_a, gmpnum_result2);
+ #endif
FREE_GMP_TEMP(temp_a);
}