From 6d71254203392b5c98cd8e080f52fdcdacbc763b Mon Sep 17 00:00:00 2001 From: NegaScout Date: Tue, 24 Dec 2024 15:10:42 +0100 Subject: [PATCH] refactor Base.GMP.MPZ.import! to be consistent with Base.GMP.MPZ.export! rename Base.GMP.MPZ.export! "dynamic" variable from `a` to `x`, since it is more in line with comment on L141 in base/gmp.jl add tests, that numbers and vectors can be exported and imported correctly and composed import and export is identity --- base/gmp.jl | 26 +++++++++++++++++--------- test/gmp.jl | 30 ++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/base/gmp.jl b/base/gmp.jl index df0d9fee49348..6e11f26635103 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -251,21 +251,29 @@ get_str!(x, a, b::BigInt) = (ccall((:__gmpz_get_str,libgmp), Ptr{Cchar}, (Ptr{Cc set_str!(x::BigInt, a, b) = Int(ccall((:__gmpz_set_str, libgmp), Cint, (mpz_t, Ptr{UInt8}, Cint), x, a, b)) get_d(a::BigInt) = ccall((:__gmpz_get_d, libgmp), Cdouble, (mpz_t,), a) -function export!(a::AbstractVector{T}, n::BigInt; order::Integer=-1, nails::Integer=0, endian::Integer=0) where {T<:Base.BitInteger} - stride(a, 1) == 1 || throw(ArgumentError("a must have stride 1")) +function export!(x::AbstractVector{T}, n::BigInt; order::Integer=-1, nails::Integer=0, endian::Integer=0) where {T<:Base.BitInteger} + stride(x, 1) == 1 || throw(ArgumentError("x must have stride 1")) ndigits = cld(sizeinbase(n, 2), 8*sizeof(T) - nails) - length(a) < ndigits && resize!(a, ndigits) + length(x) < ndigits && resize!(x, ndigits) count = Ref{Csize_t}() - ccall((:__gmpz_export, libgmp), Ptr{T}, (Ptr{T}, Ref{Csize_t}, Cint, Csize_t, Cint, Csize_t, mpz_t), - a, count, order, sizeof(T), endian, nails, n) - @assert count[] ≤ length(a) - return a, Int(count[]) + ccall((:__gmpz_export, libgmp), + Ptr{T}, + (Ptr{T}, Ref{Csize_t}, Cint, Csize_t, Cint, Csize_t, mpz_t), + x, count, order, sizeof(T), endian, nails, n) + @assert count[] ≤ length(x) + return x, Int(count[]) end limbs_write!(x::BigInt, a) = ccall((:__gmpz_limbs_write, libgmp), Ptr{Limb}, (mpz_t, Clong), x, a) limbs_finish!(x::BigInt, a) = ccall((:__gmpz_limbs_finish, libgmp), Cvoid, (mpz_t, Clong), x, a) -import!(x::BigInt, a, b, c, d, e, f) = ccall((:__gmpz_import, libgmp), Cvoid, - (mpz_t, Csize_t, Cint, Csize_t, Cint, Csize_t, Ptr{Cvoid}), x, a, b, c, d, e, f) + +function import!(x::BigInt, n::AbstractVector{T}; order::Integer=-1, nails::Integer=0, endian::Integer=0) where {T<:Base.BitInteger} + ccall((:__gmpz_import, libgmp), + Cvoid, + (mpz_t, Csize_t, Cint, Csize_t, Cint, Csize_t, Ptr{Cvoid}), + x, length(n), order, sizeof(T), endian, nails, n) + return x +end setbit!(x, a) = (ccall((:__gmpz_setbit, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a); x) tstbit(a::BigInt, b) = ccall((:__gmpz_tstbit, libgmp), Cint, (mpz_t, bitcnt_t), a, b) % Bool diff --git a/test/gmp.jl b/test/gmp.jl index 13413abe55f9d..2f5d6542445ba 100644 --- a/test/gmp.jl +++ b/test/gmp.jl @@ -445,6 +445,36 @@ end @test string(big(0), base = rand(2:62), pad = 0) == "" end +@testset "Base.GMP.MPZ.import!/export!" begin + # test import + bytes_to_import_from = Vector{UInt8}([1, 0]) + int_to_import_to = BigInt() + Base.GMP.MPZ.import!(int_to_import_to, bytes_to_import_from, order=0) + @test int_to_import_to == BigInt(256) + + # test export + int_to_export_from = BigInt(256) + bytes_to_export_to = Vector{UInt8}(undef, 2) + Base.GMP.MPZ.export!(bytes_to_export_to, int_to_export_from, order=0) + @test all(bytes_to_export_to .== bytes_to_import_from) + + # test both composed import(export) is identity + int_to_export_from = BigInt(256) + bytes_to_export_to = Vector{UInt8}(undef, 2) + Base.GMP.MPZ.export!(bytes_to_export_to, int_to_export_from, order=0) + int_to_import_to = BigInt() + Base.GMP.MPZ.import!(int_to_import_to, bytes_to_export_to, order=0) + @test int_to_export_from == int_to_import_to + + # test both composed export(import) is identity + bytes_to_import_from = Vector{UInt8}([1, 0]) + int_to_import_to = BigInt() + Base.GMP.MPZ.import!(int_to_import_to, bytes_to_import_from, order=0) + bytes_to_export_to = Vector{UInt8}(undef, 2) + Base.GMP.MPZ.export!(bytes_to_export_to, int_to_export_from, order=0) + @test all(bytes_to_export_to .== bytes_to_import_from) +end + @test isqrt(big(4)) == 2 @test isqrt(big(5)) == 2