123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461(** An interface to use for int-like types, e.g., {{!Base.Int}[Int]} and
{{!Base.Int64}[Int64]}. *)open!ImportmoduletypeRound=sigtypet(** [round] rounds an int to a multiple of a given [to_multiple_of] argument, according
to a direction [dir], with default [dir] being [`Nearest]. [round] will raise if
[to_multiple_of <= 0]. If the result overflows (too far positive or too far
negative), [round] returns an incorrect result.
{v
| `Down | rounds toward Int.neg_infinity |
| `Up | rounds toward Int.infinity |
| `Nearest | rounds to the nearest multiple, or `Up in case of a tie |
| `Zero | rounds toward zero |
v}
Here are some examples for [round ~to_multiple_of:10] for each direction:
{v
| `Down | {10 .. 19} --> 10 | { 0 ... 9} --> 0 | {-10 ... -1} --> -10 |
| `Up | { 1 .. 10} --> 10 | {-9 ... 0} --> 0 | {-19 .. -10} --> -10 |
| `Zero | {10 .. 19} --> 10 | {-9 ... 9} --> 0 | {-19 .. -10} --> -10 |
| `Nearest | { 5 .. 14} --> 10 | {-5 ... 4} --> 0 | {-15 ... -6} --> -10 |
v}
For convenience and performance, there are variants of [round] with [dir]
hard-coded. If you are writing performance-critical code you should use these. *)valround:?dir:[`Zero|`Nearest|`Up|`Down]->t->to_multiple_of:t->tvalround_towards_zero:t->to_multiple_of:t->tvalround_down:t->to_multiple_of:t->tvalround_up:t->to_multiple_of:t->tvalround_nearest:t->to_multiple_of:t->tend(** String format for integers, [to_string] / [sexp_of_t] direction only. Includes
comparisons and hash functions for [[@@deriving]]. *)moduletypeTo_string_format=sigtypet[@@deriving_inlinesexp_of,compare~localize,hash]valsexp_of_t:t->Sexplib0.Sexp.tincludePpx_compare_lib.Comparable.Swithtypet:=tincludePpx_compare_lib.Comparable.S_localwithtypet:=tincludePpx_hash_lib.Hashable.Swithtypet:=t[@@@end]valto_string:t->stringvalto_string_hum:?delimiter:char->t->stringend(** String format for integers, including both [to_string] / [sexp_of_t] and [of_string] /
[t_of_sexp] directions. Includes comparisons and hash functions for [[@@deriving]]. *)moduletypeString_format=sigtypet[@@deriving_inlinesexp,sexp_grammar,compare~localize,hash]includeSexplib0.Sexpable.Swithtypet:=tvalt_sexp_grammar:tSexplib0.Sexp_grammar.tincludePpx_compare_lib.Comparable.Swithtypet:=tincludePpx_compare_lib.Comparable.S_localwithtypet:=tincludePpx_hash_lib.Hashable.Swithtypet:=t[@@@end]includeStringable.Swithtypet:=tvalto_string_hum:?delimiter:char->t->stringend(** Binary format for integers, unsigned and starting with [0b]. *)moduletypeBinaryable=sigtypetmoduleBinary:To_string_formatwithtypet=tend(** Hex format for integers, signed and starting with [0x]. *)moduletypeHexable=sigtypetmoduleHex:String_formatwithtypet=tendmoduletypeS_common=sigtypet[@@deriving_inlinesexp,sexp_grammar]includeSexplib0.Sexpable.Swithtypet:=tvalt_sexp_grammar:tSexplib0.Sexp_grammar.t[@@@end]includeFloatable.Swithtypet:=tincludeIntable.Swithtypet:=tincludeIdentifiable.Swithtypet:=tincludeComparable.With_zerowithtypet:=tincludePpx_compare_lib.Comparable.S_localwithtypet:=tincludePpx_compare_lib.Equal.S_localwithtypet:=tincludeInvariant.Swithtypet:=tincludeHexablewithtypet:=tincludeBinaryablewithtypet:=tvalof_string_opt:string->toption(** [delimiter] is an underscore by default. *)valto_string_hum:?delimiter:char->t->string(** {2 Infix operators and constants} *)valzero:tvalone:tvalminus_one:tval(+):t->t->tval(-):t->t->tval(*):t->t->t(** Integer exponentiation *)val(**):t->t->t(** Negation *)valneg:t->tval(~-):t->t(** There are two pairs of integer division and remainder functions, [/%] and [%], and
[/] and [rem]. They both satisfy the same equation relating the quotient and the
remainder:
{[
x = (x /% y) * y + (x % y);
x = (x / y) * y + (rem x y);
]}
The functions return the same values if [x] and [y] are positive. They all raise
if [y = 0].
The functions differ if [x < 0] or [y < 0].
If [y < 0], then [%] and [/%] raise, whereas [/] and [rem] do not.
[x % y] always returns a value between 0 and [y - 1], even when [x < 0]. On the
other hand, [rem x y] returns a negative value if and only if [x < 0]; that value
satisfies [abs (rem x y) <= abs y - 1]. *)val(/%):t->t->tval(%):t->t->tval(/):t->t->tvalrem:t->t->t(** Float division of integers. *)val(//):t->t->float(** Same as [bit_and]. *)val(land):t->t->t(** Same as [bit_or]. *)val(lor):t->t->t(** Same as [bit_xor]. *)val(lxor):t->t->t(** Same as [bit_not]. *)vallnot:t->t(** Same as [shift_left]. *)val(lsl):t->int->t(** Same as [shift_right]. *)val(asr):t->int->t(** {2 Other common functions} *)includeRoundwithtypet:=t(** Returns the absolute value of the argument. May be negative if the input is
[min_value]. *)valabs:t->t(** {2 Successor and predecessor functions} *)valsucc:t->tvalpred:t->t(** {2 Exponentiation} *)(** [pow base exponent] returns [base] raised to the power of [exponent]. It is OK if
[base <= 0]. [pow] raises if [exponent < 0], or an integer overflow would occur. *)valpow:t->t->t(** {2 Bit-wise logical operations } *)(** These are identical to [land], [lor], etc. except they're not infix and have
different names. *)valbit_and:t->t->tvalbit_or:t->t->tvalbit_xor:t->t->tvalbit_not:t->t(** Returns the number of 1 bits in the binary representation of the input. *)valpopcount:t->int(** {2 Bit-shifting operations }
The results are unspecified for negative shifts and shifts [>= num_bits]. *)(** Shifts left, filling in with zeroes. *)valshift_left:t->int->t(** Shifts right, preserving the sign of the input. *)valshift_right:t->int->t(** {2 Increment and decrement functions for integer references } *)valdecr:tref->unitvalincr:tref->unit(** {2 Conversion functions to related integer types} *)valof_int32_exn:int32->tvalto_int32_exn:t->int32valof_int64_exn:int64->tvalto_int64:t->int64valof_nativeint_exn:nativeint->tvalto_nativeint_exn:t->nativeint(** [of_float_unchecked] truncates the given floating point number to an integer,
rounding towards zero.
The result is unspecified if the argument is nan or falls outside the range
of representable integers. *)valof_float_unchecked:float->tendmoduletypeOperators_unbounded=sigtypetval(+):t->t->tval(-):t->t->tval(*):t->t->tval(/):t->t->tval(~-):t->tval(**):t->t->tincludeComparisons.Infixwithtypet:=tvalabs:t->tvalneg:t->tvalzero:tval(%):t->t->tval(/%):t->t->tval(//):t->t->floatval(land):t->t->tval(lor):t->t->tval(lxor):t->t->tvallnot:t->tval(lsl):t->int->tval(asr):t->int->tendmoduletypeOperators=sigincludeOperators_unboundedval(lsr):t->int->tend(** [S_unbounded] is a generic interface for unbounded integers, e.g. [Bignum.Bigint].
[S_unbounded] is a restriction of [S] (below) that omits values that depend on
fixed-size integers. *)moduletypeS_unbounded=sigincludeS_common(** @inline *)(** A sub-module designed to be opened to make working with ints more convenient. *)moduleO:Operators_unboundedwithtypet:=tend(** [S] is a generic interface for fixed-size integers. *)moduletypeS=sigincludeS_common(** @inline *)(** The number of bits available in this integer type. Note that the integer
representations are signed. *)valnum_bits:int(** The largest representable integer. *)valmax_value:t(** The smallest representable integer. *)valmin_value:t(** Same as [shift_right_logical]. *)val(lsr):t->int->t(** Shifts right, filling in with zeroes, which will not preserve the sign of the
input. *)valshift_right_logical:t->int->t(** [ceil_pow2 x] returns the smallest power of 2 that is greater than or equal to [x].
The implementation may only be called for [x > 0]. Example: [ceil_pow2 17 = 32] *)valceil_pow2:t->t(** [floor_pow2 x] returns the largest power of 2 that is less than or equal to [x]. The
implementation may only be called for [x > 0]. Example: [floor_pow2 17 = 16] *)valfloor_pow2:t->t(** [ceil_log2 x] returns the ceiling of log-base-2 of [x], and raises if [x <= 0]. *)valceil_log2:t->int(** [floor_log2 x] returns the floor of log-base-2 of [x], and raises if [x <= 0]. *)valfloor_log2:t->int(** [is_pow2 x] returns true iff [x] is a power of 2. [is_pow2] raises if [x <= 0]. *)valis_pow2:t->bool(** Returns the number of leading zeros in the binary representation of the input, as an
integer between 0 and one less than [num_bits].
The results are unspecified for [t = 0]. *)valclz:t->int(** Returns the number of trailing zeros in the binary representation of the input, as
an integer between 0 and one less than [num_bits].
The results are unspecified for [t = 0]. *)valctz:t->int(** A sub-module designed to be opened to make working with ints more convenient. *)moduleO:Operatorswithtypet:=tendmoduletypeInt_without_module_types=sig(** OCaml's native integer type.
The number of bits in an integer is platform dependent, being 31-bits on a 32-bit
platform, and 63-bits on a 64-bit platform. [int] is a signed integer type. [int]s
are also subject to overflow, meaning that [Int.max_value + 1 = Int.min_value].
[int]s always fit in a machine word. *)typet=int[@@deriving_inlineglobalize]valglobalize:t->t[@@@end]includeSwithtypet:=t(** @inline *)moduleO:sig(*_ Declared as externals so that the compiler skips the caml_apply_X wrapping even
when compiling without cross library inlining. *)external(+):(t[@local_opt])->(t[@local_opt])->t="%addint"external(-):(t[@local_opt])->(t[@local_opt])->t="%subint"external(*):(t[@local_opt])->(t[@local_opt])->t="%mulint"external(/):(t[@local_opt])->(t[@local_opt])->t="%divint"external(~-):(t[@local_opt])->t="%negint"val(**):t->t->texternal(=):(t[@local_opt])->(t[@local_opt])->bool="%equal"external(<>):(t[@local_opt])->(t[@local_opt])->bool="%notequal"external(<):(t[@local_opt])->(t[@local_opt])->bool="%lessthan"external(>):(t[@local_opt])->(t[@local_opt])->bool="%greaterthan"external(<=):(t[@local_opt])->(t[@local_opt])->bool="%lessequal"external(>=):(t[@local_opt])->(t[@local_opt])->bool="%greaterequal"external(land):(t[@local_opt])->(t[@local_opt])->t="%andint"external(lor):(t[@local_opt])->(t[@local_opt])->t="%orint"external(lxor):(t[@local_opt])->(t[@local_opt])->t="%xorint"vallnot:t->tvalabs:t->texternalneg:(t[@local_opt])->t="%negint"valzero:tval(%):t->t->tval(/%):t->t->tval(//):t->t->floatexternal(lsl):(t[@local_opt])->(int[@local_opt])->t="%lslint"external(asr):(t[@local_opt])->(int[@local_opt])->t="%asrint"external(lsr):(t[@local_opt])->(int[@local_opt])->t="%lsrint"endincludemoduletypeofO(** [max_value_30_bits = 2^30 - 1]. It is useful for writing tests that work on both
64-bit and 32-bit platforms. *)valmax_value_30_bits:t(** {2 Conversion functions} *)valof_int:int->tvalto_int:t->intvalof_int32:int32->toptionvalto_int32:t->int32optionvalof_int64:int64->toptionvalof_nativeint:nativeint->toptionvalto_nativeint:t->nativeint(** {3 Truncating conversions}
These functions return the least-significant bits of the input. In cases
where optional conversions return [Some x], truncating conversions return [x]. *)(*_ Declared as externals so that the compiler skips the caml_apply_X wrapping even when
compiling without cross library inlining. *)externalto_int32_trunc:(t[@local_opt])->(int32[@local_opt])="%int32_of_int"externalof_int32_trunc:(int32[@local_opt])->t="%int32_to_int"externalof_int64_trunc:(int64[@local_opt])->t="%int64_to_int"externalof_nativeint_trunc:(nativeint[@local_opt])->t="%nativeint_to_int"(** {2 Byte swap operations}
Byte swap operations reverse the order of bytes in an integer. For
example, {!Int32.bswap32} reorders the bottom 32 bits (or 4 bytes),
turning [0x1122_3344] to [0x4433_2211]. Byte swap functions exposed by
Base use OCaml primitives to generate assembly instructions to perform
the relevant byte swaps.
For a more extensive list of byteswap functions, see {!Int32} and
{!Int64}.
*)(** Byte swaps bottom 16 bits (2 bytes). The values of the remaining bytes
are undefined. *)externalbswap16:(int[@local_opt])->int="%bswap16"(*_ Declared as an external so that the compiler skips the caml_apply_X wrapping even
when compiling without cross library inlining. *)(**/**)(*_ See the Jane Street Style Guide for an explanation of [Private] submodules:
https://opensource.janestreet.com/standards/#private-submodules *)modulePrivate:sig(*_ For ../bench/bench_int.ml *)moduleO_F:sigval(%):int->int->intval(/%):int->int->intval(//):int->int->floatendendendmoduletypeInt=sigincludeInt_without_module_types(** @inline *)(** {2 Module types specifying integer operations.} *)moduletypeBinaryable=BinaryablemoduletypeHexable=HexablemoduletypeInt_without_module_types=Int_without_module_typesmoduletypeOperators=OperatorsmoduletypeOperators_unbounded=Operators_unboundedmoduletypeRound=RoundmoduletypeS=SmoduletypeS_common=S_commonmoduletypeS_unbounded=S_unboundedmoduletypeString_format=String_formatmoduletypeTo_string_format=To_string_formatend