sig
  external gmp_compiled_version : unit -> int * int * int
    = "mlgmp_compiled_version"
  external gmp_compiled_version_string : unit -> string
    = "mlgmp_compiled_version_string"
  external gmp_get_version_string : unit -> string
    = "mlgmp_get_version_string"
  type z
  type byte_order = [ `B | `L | `N ]
  external z_of_based_string : base:int -> string -> Gmp.z
    = "mlgmp_z_of_based_string"
  val z_of_string : string -> Gmp.z
  external based_string_of_z : base:int -> Gmp.z -> string
    = "mlgmp_based_string_of_z"
  val string_of_z : Gmp.z -> string
  external z_of_int : int -> Gmp.z = "mlgmp_z_of_int"
  external int_of_z : Gmp.z -> int = "mlgmp_int_of_z"
  external z_of_int32 : int32 -> Gmp.z = "mlgmp_z_of_int32"
  external int32_of_z : Gmp.z -> int32 = "mlgmp_int32_of_z"
  external z_of_int64 : int64 -> Gmp.z = "mlgmp_z_of_int64"
  external int64_of_z : Gmp.z -> int64 = "mlgmp_int64_of_z"
  external z_of_nativeint : nativeint -> Gmp.z = "mlgmp_z_of_nativeint"
  external nativeint_of_z : Gmp.z -> nativeint = "mlgmp_nativeint_of_z"
  external z_of_truncated_float : float -> Gmp.z
    = "mlgmp_z_of_truncated_float"
  external float_of_z : Gmp.z -> float = "mlgmp_float_of_z"
  module Z :
    sig
      type t = Gmp.z
      val zero : Gmp.Z.t
      val one : Gmp.Z.t
      val minus_one : Gmp.Z.t
      external compare : Gmp.Z.t -> Gmp.Z.t -> int = "mlgmp_z_compare"
      external compare_int : Gmp.Z.t -> int -> int = "mlgmp_z_compare_int"
      external neg : Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_neg"
      external abs : Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_abs"
      external add : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_add"
      external add_int : Gmp.Z.t -> int -> Gmp.Z.t = "mlgmp_z_add_int"
      external sub : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_sub"
      external sub_int : Gmp.Z.t -> int -> Gmp.Z.t = "mlgmp_z_sub_int"
      external mul : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_mul"
      external mul_int : Gmp.Z.t -> int -> Gmp.Z.t = "mlgmp_z_mul_int"
      external div : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_div"
      external fma : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_fma"
      external pow_int : base:Gmp.Z.t -> exponent:int -> Gmp.Z.t
        = "mlgmp_z_pow_int"
      external int_pow_int : base:int -> exponent:int -> Gmp.Z.t
        = "mlgmp_z_int_pow_int"
      external scale : Gmp.Z.t -> base:int -> exponent:int -> Gmp.Z.t
        = "mlgmp_z_scale"
      external root : nth:int -> Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_root"
      external sqrt : Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_sqrt"
      external rem : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_rem"
      external modulo : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_modulo"
      external pow_mod :
        base:Gmp.Z.t -> exponent:Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t
        = "mlgmp_z_pow_mod"
      external tdiv : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t * Gmp.Z.t
        = "mlgmp_z_tdiv"
      external tdiv_int : Gmp.Z.t -> int -> Gmp.Z.t * int
        = "mlgmp_z_tdiv_int"
      external cdiv : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t * Gmp.Z.t
        = "mlgmp_z_cdiv"
      external cdiv_int : Gmp.Z.t -> int -> Gmp.Z.t * int
        = "mlgmp_z_cdiv_int"
      external fdiv : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t * Gmp.Z.t
        = "mlgmp_z_fdiv"
      external fdiv_int : Gmp.Z.t -> int -> Gmp.Z.t * int
        = "mlgmp_z_fdiv_int"
      external tsqrt : Gmp.Z.t -> Gmp.Z.t * Gmp.Z.t = "mlgmp_z_tsqrt"
      external is_perfect_power : Gmp.Z.t -> bool
        = "mlgmp_z_is_perfect_power"
      external is_perfect_square : Gmp.Z.t -> bool
        = "mlgmp_z_is_perfect_square"
      external is_probably_prime : Gmp.Z.t -> int -> int
        = "mlgmp_z_is_probably_prime"
      external next_prime : Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_next_prime"
      external gcd : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_gcd"
      external gcdext : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t * Gmp.Z.t * Gmp.Z.t
        = "mlgmp_z_gcdext"
      external lcm : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_lcm"
      external invert : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t option
        = "mlgmp_z_invert"
      external jacobi : Gmp.Z.t -> Gmp.Z.t -> int = "mlgmp_z_jacobi"
      val legendre : Gmp.Z.t -> Gmp.Z.t -> int
      val kronecker : Gmp.Z.t -> Gmp.Z.t -> int
      external remove : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t * int
        = "mlgmp_z_remove"
      external fac_int : int -> Gmp.Z.t = "mlgmp_z_fac_int"
      external dfac_int : int -> Gmp.Z.t = "mlgmp_z_dfac_int"
      external int_mfac_int : step:int -> int -> Gmp.Z.t
        = "mlgmp_z_int_mfac_int"
      external primorial_int : int -> Gmp.Z.t = "mlgmp_z_primorial_int"
      external bin_int : Gmp.Z.t -> int -> Gmp.Z.t = "mlgmp_z_bin_int"
      external fib_int : int -> Gmp.Z.t = "mlgmp_z_fib_int"
      external lucnum_int : int -> Gmp.Z.t = "mlgmp_z_lucnum_int"
      external logand : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_logand"
      external logand_int : Gmp.Z.t -> int -> Gmp.Z.t = "mlgmp_z_logand_int"
      external logor : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_logor"
      external logor_int : Gmp.Z.t -> int -> Gmp.Z.t = "mlgmp_z_logor_int"
      external logxor : Gmp.Z.t -> Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_logxor"
      external logxor_int : Gmp.Z.t -> int -> Gmp.Z.t = "mlgmp_z_logxor_int"
      external lognot : Gmp.Z.t -> Gmp.Z.t = "mlgmp_z_lognot"
      external shift_left : Gmp.Z.t -> int -> Gmp.Z.t = "mlgmp_z_shift_left"
      external shift_right : Gmp.Z.t -> int -> Gmp.Z.t
        = "mlgmp_z_shift_right"
      external population_count : Gmp.Z.t -> int = "mlgmp_z_population_count"
      external hamming_distance : Gmp.Z.t -> Gmp.Z.t -> int
        = "mlgmp_z_hamming_distance"
      external scan0 : Gmp.Z.t -> int -> int = "mlgmp_z_scan0"
      external scan1 : Gmp.Z.t -> int -> int = "mlgmp_z_scan1"
      external set_bit : Gmp.Z.t -> int -> Gmp.Z.t = "mlgmp_z_set_bit"
      external clear_bit : Gmp.Z.t -> int -> Gmp.Z.t = "mlgmp_z_clear_bit"
      external test_bit : Gmp.Z.t -> int -> int = "mlgmp_z_test_bit"
      external of_based_string : base:int -> string -> Gmp.Z.t
        = "mlgmp_z_of_based_string"
      val of_string : string -> Gmp.Z.t
      external to_based_string : base:int -> Gmp.Z.t -> string
        = "mlgmp_based_string_of_z"
      val to_string : Gmp.Z.t -> string
      external of_int : int -> Gmp.Z.t = "mlgmp_z_of_int"
      external to_int : Gmp.Z.t -> int = "mlgmp_int_of_z"
      external of_int32 : int32 -> Gmp.Z.t = "mlgmp_z_of_int32"
      external to_int32 : int32 -> Gmp.Z.t = "mlgmp_int32_of_z"
      external of_int64 : int64 -> Gmp.Z.t = "mlgmp_z_of_int64"
      external to_int64 : Gmp.Z.t -> int64 = "mlgmp_int64_of_z"
      external of_nativeint : nativeint -> Gmp.Z.t = "mlgmp_z_of_nativeint"
      external to_nativeint : nativeint -> Gmp.Z.t = "mlgmp_nativeint_of_z"
      external to_float : Gmp.Z.t -> float = "mlgmp_float_of_z"
      external export_length : Gmp.Z.t -> int = "mlgmp_z_export_length"
      val export :
        order:Gmp.byte_order -> Gmp.Z.t -> bytes -> int -> int -> unit
      val import :
        order:Gmp.byte_order -> signed:bool -> bytes -> int -> int -> Gmp.Z.t
    end
  type q
  external q_of_based_string : base:int -> string -> Gmp.q
    = "mlgmp_q_of_based_string"
  val q_of_string : string -> Gmp.q
  external based_string_of_q : base:int -> Gmp.q -> string
    = "mlgmp_based_string_of_q"
  val string_of_q : Gmp.q -> string
  external q_of_int : int -> Gmp.q = "mlgmp_q_of_int"
  external q_of_float : float -> Gmp.q = "mlgmp_q_of_float"
  external float_of_q : Gmp.q -> float = "mlgmp_float_of_q"
  external q_of_z : Gmp.z -> Gmp.q = "mlgmp_q_of_z"
  external z_of_truncated_q : Gmp.q -> Gmp.z = "mlgmp_z_of_truncated_q"
  module Q :
    sig
      type t = Gmp.q
      val zero : Gmp.Q.t
      val one : Gmp.Q.t
      val minus_one : Gmp.Q.t
      external compare : Gmp.Q.t -> Gmp.Q.t -> int = "mlgmp_q_compare"
      external compare_int : Gmp.Q.t -> int -> int = "mlgmp_q_compare_int"
      external neg : Gmp.Q.t -> Gmp.Q.t = "mlgmp_q_neg"
      external abs : Gmp.Q.t -> Gmp.Q.t = "mlgmp_q_abs"
      external add : Gmp.Q.t -> Gmp.Q.t -> Gmp.Q.t = "mlgmp_q_add"
      external add_int : Gmp.Q.t -> int -> Gmp.Q.t = "mlgmp_q_add_int"
      external sub : Gmp.Q.t -> Gmp.Q.t -> Gmp.Q.t = "mlgmp_q_sub"
      external sub_int : Gmp.Q.t -> int -> Gmp.Q.t = "mlgmp_q_sub_int"
      external mul : Gmp.Q.t -> Gmp.Q.t -> Gmp.Q.t = "mlgmp_q_mul"
      external mul_int : Gmp.Q.t -> int -> Gmp.Q.t = "mlgmp_q_mul_int"
      external div : Gmp.Q.t -> Gmp.Q.t -> Gmp.Q.t = "mlgmp_q_div"
      external fma : Gmp.Q.t -> Gmp.Q.t -> Gmp.Q.t -> Gmp.Q.t = "mlgmp_q_fma"
      external pow_int : base:Gmp.Q.t -> exponent:int -> Gmp.Q.t
        = "mlgmp_q_pow_int"
      external int_pow_int : base:int -> exponent:int -> Gmp.Q.t
        = "mlgmp_q_int_pow_int"
      external scale : Gmp.Q.t -> base:int -> exponent:int -> Gmp.Q.t
        = "mlgmp_q_scale"
      external root : nth:int -> Gmp.Q.t -> Gmp.Q.t = "mlgmp_q_root"
      external sqrt : Gmp.Q.t -> Gmp.Q.t = "mlgmp_q_sqrt"
      external num : Gmp.Q.t -> Gmp.z = "mlgmp_q_num"
      external den : Gmp.Q.t -> Gmp.z = "mlgmp_q_den"
      external of_based_string : base:int -> string -> Gmp.Q.t
        = "mlgmp_q_of_based_string"
      val of_string : string -> Gmp.Q.t
      external to_based_string : base:int -> Gmp.Q.t -> string
        = "mlgmp_based_string_of_q"
      val to_string : Gmp.Q.t -> string
      external of_int : int -> Gmp.Q.t = "mlgmp_q_of_int"
      external of_float : float -> Gmp.Q.t = "mlgmp_q_of_float"
      external to_float : Gmp.Q.t -> float = "mlgmp_float_of_q"
      external of_z : Gmp.z -> Gmp.Q.t = "mlgmp_q_of_z"
      external make_int : int -> int -> Gmp.Q.t = "mlgmp_q_make_int"
      external make_z : Gmp.z -> Gmp.z -> Gmp.Q.t = "mlgmp_q_make_z"
    end
  type f
  external f_of_based_string : prec:int -> base:int -> string -> Gmp.f
    = "mlgmp_f_of_based_string"
  val f_of_string : prec:int -> string -> Gmp.f
  external based_string_of_f : base:int -> Gmp.f -> string
    = "mlgmp_based_string_of_f"
  val string_of_f : Gmp.f -> string
  external f_get_str : base:int -> int -> Gmp.f -> string * int
    = "mlgmp_f_get_str"
  external f_of_int : prec:int -> int -> Gmp.f = "mlgmp_f_of_int"
  external f_of_float : prec:int -> float -> Gmp.f = "mlgmp_f_of_float"
  external float_of_f : Gmp.f -> float = "mlgmp_float_of_f"
  external f_of_z : prec:int -> Gmp.z -> Gmp.f = "mlgmp_f_of_z"
  external z_of_truncated_f : Gmp.f -> Gmp.z = "mlgmp_z_of_truncated_f"
  external f_of_f : prec:int -> Gmp.f -> Gmp.f = "mlgmp_f_of_f"
  module F :
    sig
      type t = Gmp.f
      val zero : prec:int -> Gmp.F.t
      val one : prec:int -> Gmp.F.t
      val minus_one : prec:int -> Gmp.F.t
      external compare : Gmp.F.t -> Gmp.F.t -> int = "mlgmp_f_compare"
      external compare_int : Gmp.F.t -> int -> int = "mlgmp_f_compare_int"
      external neg : prec:int -> Gmp.F.t -> Gmp.F.t = "mlgmp_f_neg"
      external abs : prec:int -> Gmp.F.t -> Gmp.F.t = "mlgmp_f_abs"
      external add : prec:int -> Gmp.F.t -> Gmp.F.t -> Gmp.F.t
        = "mlgmp_f_add"
      external add_int : prec:int -> Gmp.F.t -> int -> Gmp.F.t
        = "mlgmp_f_add_int"
      external sub : prec:int -> Gmp.F.t -> Gmp.F.t -> Gmp.F.t
        = "mlgmp_f_sub"
      external sub_int : prec:int -> Gmp.F.t -> int -> Gmp.F.t
        = "mlgmp_f_sub_int"
      external mul : prec:int -> Gmp.F.t -> Gmp.F.t -> Gmp.F.t
        = "mlgmp_f_mul"
      external mul_int : prec:int -> Gmp.F.t -> int -> Gmp.F.t
        = "mlgmp_f_mul_int"
      external div : prec:int -> Gmp.F.t -> Gmp.F.t -> Gmp.F.t
        = "mlgmp_f_div"
      external fma : prec:int -> Gmp.F.t -> Gmp.F.t -> Gmp.F.t -> Gmp.F.t
        = "mlgmp_f_fma"
      external pow_int : prec:int -> base:Gmp.F.t -> exponent:int -> Gmp.F.t
        = "mlgmp_f_pow_int"
      external int_pow_int : prec:int -> base:int -> exponent:int -> Gmp.F.t
        = "mlgmp_f_int_pow_int"
      external scale :
        prec:int -> Gmp.F.t -> base:int -> exponent:int -> Gmp.F.t
        = "mlgmp_f_scale"
      external root : prec:int -> nth:int -> Gmp.F.t -> Gmp.F.t
        = "mlgmp_f_root"
      external sqrt : prec:int -> Gmp.F.t -> Gmp.F.t = "mlgmp_f_sqrt"
      external nearly_equal : int -> Gmp.F.t -> Gmp.F.t -> bool
        = "mlgmp_f_nearly_equal"
      external frexp : prec:int -> Gmp.F.t -> Gmp.F.t * int = "mlgmp_f_frexp"
      external ldexp : prec:int -> Gmp.F.t -> int -> Gmp.F.t
        = "mlgmp_f_ldexp"
      external trunc : prec:int -> Gmp.F.t -> Gmp.F.t = "mlgmp_f_trunc"
      external ceil : prec:int -> Gmp.F.t -> Gmp.F.t = "mlgmp_f_ceil"
      external floor : prec:int -> Gmp.F.t -> Gmp.F.t = "mlgmp_f_floor"
      external log : prec:int -> Gmp.F.t -> Gmp.F.t = "mlgmp_f_log"
      external based_log : prec:int -> base:int -> Gmp.F.t -> Gmp.F.t
        = "mlgmp_f_based_log"
      external of_based_string : prec:int -> base:int -> string -> Gmp.F.t
        = "mlgmp_f_of_based_string"
      val of_string : prec:int -> string -> Gmp.F.t
      external to_based_string : base:int -> Gmp.F.t -> string
        = "mlgmp_based_string_of_f"
      val to_string : Gmp.F.t -> string
      external of_int : prec:int -> int -> Gmp.F.t = "mlgmp_f_of_int"
      external of_float : prec:int -> float -> Gmp.F.t = "mlgmp_f_of_float"
      external to_float : Gmp.F.t -> float = "mlgmp_float_of_f"
      external of_z : prec:int -> Gmp.z -> Gmp.F.t = "mlgmp_f_of_z"
      module type Param = sig val prec : int end
      module Make :
        Param ->
          sig
            type t = Gmp.f
            val zero : Gmp.F.Make.t
            val one : Gmp.F.Make.t
            val minus_one : Gmp.F.Make.t
            external compare : Gmp.F.Make.t -> Gmp.F.Make.t -> int
              = "mlgmp_f_compare"
            external compare_int : Gmp.F.Make.t -> int -> int
              = "mlgmp_f_compare_int"
            val neg : Gmp.F.Make.t -> Gmp.F.Make.t
            val abs : Gmp.F.Make.t -> Gmp.F.Make.t
            val add : Gmp.F.Make.t -> Gmp.F.Make.t -> Gmp.F.Make.t
            val add_int : Gmp.F.Make.t -> int -> Gmp.F.Make.t
            val sub : Gmp.F.Make.t -> Gmp.F.Make.t -> Gmp.F.Make.t
            val sub_int : Gmp.F.Make.t -> int -> Gmp.F.Make.t
            val mul : Gmp.F.Make.t -> Gmp.F.Make.t -> Gmp.F.Make.t
            val mul_int : Gmp.F.Make.t -> int -> Gmp.F.Make.t
            val div : Gmp.F.Make.t -> Gmp.F.Make.t -> Gmp.F.Make.t
            val fma :
              Gmp.F.Make.t -> Gmp.F.Make.t -> Gmp.F.Make.t -> Gmp.F.Make.t
            val pow_int : base:Gmp.F.Make.t -> exponent:int -> Gmp.F.Make.t
            val int_pow_int : base:int -> exponent:int -> Gmp.F.Make.t
            val scale :
              Gmp.F.Make.t -> base:int -> exponent:int -> Gmp.F.Make.t
            val root : nth:int -> Gmp.F.Make.t -> Gmp.F.Make.t
            val sqrt : Gmp.F.Make.t -> Gmp.F.Make.t
            external nearly_equal :
              int -> Gmp.F.Make.t -> Gmp.F.Make.t -> bool
              = "mlgmp_f_nearly_equal"
            val frexp : Gmp.F.Make.t -> Gmp.F.Make.t * int
            val ldexp : Gmp.F.Make.t -> int -> Gmp.F.Make.t
            val trunc : Gmp.F.Make.t -> Gmp.F.Make.t
            val ceil : Gmp.F.Make.t -> Gmp.F.Make.t
            val floor : Gmp.F.Make.t -> Gmp.F.Make.t
            val log : Gmp.F.Make.t -> Gmp.F.Make.t
            val based_log : base:int -> Gmp.F.Make.t -> Gmp.F.Make.t
            val of_based_string : base:int -> string -> Gmp.F.Make.t
            val of_string : string -> Gmp.F.Make.t
            external to_based_string : base:int -> Gmp.F.Make.t -> string
              = "mlgmp_based_string_of_f"
            val to_string : Gmp.F.Make.t -> string
            val of_int : int -> Gmp.F.Make.t
            val of_float : float -> Gmp.F.Make.t
            external to_float : Gmp.F.Make.t -> float = "mlgmp_float_of_f"
            val of_z : Gmp.z -> Gmp.F.Make.t
          end
      external default_prec : unit -> int = "mlgmp_f_default_prec"
      val default : unit -> (module Gmp.F.Param)
    end
  module Random = Gmp.Random
end