gmp, The GNU Multiple Precision Arithmetic Library
 
Free library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating point numbers.

Website: https://www.gmplib.org
Platforms supported: Win32, Win64, Linux, FreeBSD, Haiku
Headers to include: gmp.bi
Header version: 6.0.0

Haiku R1 beta 6 amd64: `examples/manual/libraries/gmp.bas` compiled and ran
with FreeBASIC 1.20.4-3 against HaikuPorts GMP 6.3.0, computing `2^65536`.

Native types and ownership
The Win64 SDK uses 64-bit mp_limb_t values while C long remains 32-bit. mp_bitcnt_t, mp_size_t and mp_exp_t keep their C widths. Use the binding's named types for limb pointers and low-level calls; FreeBASIC Integer is not a general replacement for a C type.

mpz_get_str(0, ...) allocates through GMP's current allocator. Release such a string through the corresponding registered GMP free function, obtained with mp_get_memory_functions. The example supplies a FreeBASIC-owned buffer instead, sized by mpz_sizeinbase plus two bytes for a sign and terminating zero, and releases it with Deallocate. Release initialized number internals with mpz_clear before freeing the caller's number buffer.

The installed GMP 6.3.0 SDK has been checked against native C layouts and actual high-bit limb arguments and carry returns on Win32 and Win64, with both FreeBASIC backends. The decimal example's complete 19,729-digit result is checked independently.

Example

'' examples/manual/libraries/gmp.bas
''
'' Example extracted from the FreeBASIC Manual
'' from topic 'gmp, The GNU Multiple Precision Arithmetic Library'
'' Purpose: Compute and print 2^65536 through the native GMP library.
'' Responsibilities: Own the number buffer and decimal output storage.
'' This example contains no custom GMP allocator or limb arithmetic.
''
'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=ExtLibgmp
'' --------
''
'' Ownership:
''
'' The example owns the __mpz_struct buffer allocated for bignum and the
'' output string supplied to mpz_get_str().  Each is released on its matching
'' successful allocation path.

#include Once "gmp.bi"

Dim As Integer status = 0
Dim As mpz_ptr bignum = Allocate(SizeOf(__mpz_struct))
If bignum = 0 Then
    Print "Unable to allocate the GMP number."
    status = 1
Else
    mpz_init_set_si(bignum, 2)
    mpz_pow_ui(bignum, bignum, 65536)

    Print "2^65536 = ";
    ' GMP can use a custom allocator. Supply our own output buffer so that
    ' Deallocate() never receives memory owned by the library's allocator.
    ' Two extra bytes cover a possible sign and the terminating zero.
    Dim As UInteger digits = mpz_sizeinbase(bignum, 10)
    Dim As ZString Ptr s
    If digits > 0 AndAlso digits <= CUInt(-1) - 2 Then s = Allocate(digits + 2)
    If s <> 0 Then
        If mpz_get_str(s, 10, bignum) <> 0 Then
            Print *s;
        Else
            Print "<conversion failed>";
            status = 1
        End If
        Deallocate(s)
        s = 0
    Else
        Print "<output allocation failed>";
        status = 1
    End If
    Print

    mpz_clear(bignum)
    Deallocate(bignum)
    bignum = 0
End If

End status
'' end of examples/manual/libraries/gmp.bas