import java.lang.foreign.Arena;import java.lang.foreign.FunctionDescriptor;import java.lang.foreign.Linker;import java.lang.foreign.MemoryLayout;import java.lang.foreign.MemorySegment;import java.lang.foreign.StructLayout;import java.lang.foreign.SymbolLookup;import java.lang.invoke.MethodHandle;import static java.lang.foreign.ValueLayout.ADDRESS;import static java.lang.foreign.ValueLayout.JAVA_INT;import static java.lang.foreign.ValueLayout.JAVA_LONG;/*** <p>compile with: -J-Duser.language=en* <p>run with: --enable-native-access=ALL-UNNAMED** @see <a href="https://openjdk.org/jeps/434">FFI reference</a>*/@SuppressWarnings("OptionalGetWithoutIsPresent")public class TestGmp {public static final StructLayout mpz_struct;public static final MethodHandle mpz_init;public static final MethodHandle mpz_init_set_si;public static final MethodHandle mpz_init_set_ui;public static final MethodHandle mpz_clear;public static final MethodHandle mpz_realloc;public static final MethodHandle mpz_get_si;public static final MethodHandle mpz_get_ui;public static final MethodHandle mpz_set_si;public static final MethodHandle mpz_set_ui;public static final MethodHandle mpz_add;public static final MethodHandle mpz_addmul_ui;public static final MethodHandle mpz_submul_ui;public static final MethodHandle mpz_mul_ui;public static final MethodHandle mpz_tdiv_q;public static final MethodHandle mpz_cmp;static {// https://gmplib.org/// need MinGW-w64, msys-1.0// export ABI=64// export CC=x86_64-w64-mingw32-gcc// ./configure --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --disable-static --enable-shared --enable-fat// makevar libGmp = SymbolLookup.libraryLookup("libgmp-10.dll", Arena.global());var linker = Linker.nativeLinker();mpz_struct = MemoryLayout.structLayout(JAVA_INT.withName("mp_alloc"), // alloc count of mp_limb_t in mp_dJAVA_INT.withName("mp_size"), // current used count of mp_limb_t in mp_dADDRESS.withName("mp_d") // mp_limb_t* (GMP_LIMB_BITS=64));mpz_init = linker.downcallHandle(libGmp.find("__gmpz_init").get(), // must call mpz_clear before init againFunctionDescriptor.ofVoid(ADDRESS));mpz_init_set_si = linker.downcallHandle(libGmp.find("__gmpz_init_set_si").get(),FunctionDescriptor.ofVoid(ADDRESS, JAVA_LONG));mpz_init_set_ui = linker.downcallHandle(libGmp.find("__gmpz_init_set_ui").get(),FunctionDescriptor.ofVoid(ADDRESS, JAVA_LONG));mpz_clear = linker.downcallHandle(libGmp.find("__gmpz_clear").get(), // not safe if call twice, then init againFunctionDescriptor.ofVoid(ADDRESS));mpz_realloc = linker.downcallHandle(libGmp.find("__gmpz_realloc").get(), // must call after initFunctionDescriptor.ofVoid(ADDRESS));mpz_get_si = linker.downcallHandle(libGmp.find("__gmpz_get_si").get(), // only lowest (GMP_LIMB_BITS-1) bitsFunctionDescriptor.of(JAVA_LONG, ADDRESS));mpz_get_ui = linker.downcallHandle(libGmp.find("__gmpz_get_ui").get(), // only lowest GMP_LIMB_BITS bitsFunctionDescriptor.of(JAVA_LONG, ADDRESS));mpz_set_si = linker.downcallHandle(libGmp.find("__gmpz_set_si").get(),FunctionDescriptor.ofVoid(ADDRESS, JAVA_LONG));mpz_set_ui = linker.downcallHandle(libGmp.find("__gmpz_set_ui").get(),FunctionDescriptor.ofVoid(ADDRESS, JAVA_LONG));mpz_add = linker.downcallHandle(libGmp.find("__gmpz_add").get(),FunctionDescriptor.ofVoid(ADDRESS, ADDRESS, ADDRESS));mpz_addmul_ui = linker.downcallHandle(libGmp.find("__gmpz_addmul_ui").get(),FunctionDescriptor.ofVoid(ADDRESS, ADDRESS, JAVA_LONG));mpz_submul_ui = linker.downcallHandle(libGmp.find("__gmpz_submul_ui").get(),FunctionDescriptor.ofVoid(ADDRESS, ADDRESS, JAVA_LONG));mpz_mul_ui = linker.downcallHandle(libGmp.find("__gmpz_mul_ui").get(),FunctionDescriptor.ofVoid(ADDRESS, ADDRESS, JAVA_LONG));mpz_tdiv_q = linker.downcallHandle(libGmp.find("__gmpz_tdiv_q").get(),FunctionDescriptor.ofVoid(ADDRESS, ADDRESS, ADDRESS));mpz_cmp = linker.downcallHandle(libGmp.find("__gmpz_cmp").get(),FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS));}static final MemorySegment tmp1_Pointer = Arena.global().allocate(mpz_struct);static final MemorySegment tmp2_Pointer = Arena.global().allocate(mpz_struct);static final MemorySegment acc_Pointer = Arena.global().allocate(mpz_struct);static final MemorySegment den_Pointer = Arena.global().allocate(mpz_struct);static final MemorySegment num_Pointer = Arena.global().allocate(mpz_struct);static long extract_Digit(final long nth) throws Throwable {// joggling between tmp1_Pointer and tmp2_Pointer, so GMP won't have to// use temp buffersmpz_mul_ui.invoke(tmp1_Pointer, num_Pointer, nth);mpz_add.invoke(tmp2_Pointer, tmp1_Pointer, acc_Pointer);mpz_tdiv_q.invoke(tmp1_Pointer, tmp2_Pointer, den_Pointer);return (long)mpz_get_ui.invoke(tmp1_Pointer);}static void eliminate_Digit(final long d) throws Throwable {mpz_submul_ui.invoke(acc_Pointer, den_Pointer, d);mpz_mul_ui.invoke(acc_Pointer, acc_Pointer, 10);mpz_mul_ui.invoke(num_Pointer, num_Pointer, 10);}static void next_Term(final long k) throws Throwable {final long k2 = k * 2 + 1;mpz_addmul_ui.invoke(acc_Pointer, num_Pointer, 2);mpz_mul_ui.invoke(acc_Pointer, acc_Pointer, k2);mpz_mul_ui.invoke(den_Pointer, den_Pointer, k2);mpz_mul_ui.invoke(num_Pointer, num_Pointer, k);}public static void testBench() throws Throwable {final long n = 10000;mpz_init_set_ui.invoke(tmp1_Pointer, 0);mpz_init_set_ui.invoke(tmp2_Pointer, 0);mpz_init_set_ui.invoke(acc_Pointer, 0);mpz_init_set_ui.invoke(den_Pointer, 1);mpz_init_set_ui.invoke(num_Pointer, 1);final StringBuilder results = new StringBuilder();for (long i = 0, k = 0; i < n; ) {next_Term(++k);if ((int)mpz_cmp.invoke(num_Pointer, acc_Pointer) > 0)continue;final long d = extract_Digit(3);if (d != extract_Digit(4))continue;results.append(d);if (++i % 10 == 0)results.append("\t:").append(i).append("\n");eliminate_Digit(d);}System.out.print(results);}public static void main(String[] args) throws Throwable {testBench();var ms = Arena.ofAuto().allocate(mpz_struct);mpz_init_set_si.invoke(ms, 1234);System.out.println(mpz_get_si.invoke(ms));mpz_clear.invoke(ms);System.out.println("end");}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。