123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152(**************************************************************************)(* *)(* OCaml *)(* *)(* The OCaml programmers *)(* *)(* Copyright 2018 Institut National de Recherche en Informatique et *)(* en Automatique. *)(* *)(* All rights reserved. This file is distributed under the terms of *)(* the GNU Lesser General Public License version 2.1, with the *)(* special exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)typet=intletzero=0letone=1letminus_one=-1externalneg:int->int="%negint"externaladd:int->int->int="%addint"externalsub:int->int->int="%subint"externalmul:int->int->int="%mulint"externaldiv:int->int->int="%divint"externalrem:int->int->int="%modint"externalsucc:int->int="%succint"externalpred:int->int="%predint"letabsx=ifx>=0thenxelse-xletmax_int=(-1)lsr1letmin_int=max_int+1externallogand:int->int->int="%andint"externallogor:int->int->int="%orint"externallogxor:int->int->int="%xorint"letlognotx=logxorx(-1)externalshift_left:int->int->int="%lslint"externalshift_right:int->int->int="%asrint"externalshift_right_logical:int->int->int="%lsrint"letequal:int->int->bool=(=)letcompare:int->int->int=Stdlib.compareletminxy:t=ifx<=ythenxelseyletmaxxy:t=ifx>=ythenxelsey(* Number of leading zeros. Hacker's Delight (2 ed.), algorithm 5.12 *)letleading_zerosx=letx=refxandn=refSys.int_sizeinifSys.int_size>32thenbeginlety=shift_right_logical!x32inify<>0then(n:=!n-32;x:=y)end;lety=shift_right_logical!x16inify<>0then(n:=!n-16;x:=y);lety=shift_right_logical!x8inify<>0then(n:=!n-8;x:=y);lety=shift_right_logical!x4inify<>0then(n:=!n-4;x:=y);lety=shift_right_logical!x2inify<>0then(n:=!n-2;x:=y);lety=shift_right_logical!x1inify<>0then!n-2else!n-!xletunsigned_bitsizex=Sys.int_size-leading_zerosx(* Number of leading sign bits. *)letleading_sign_bitsx=ifx>=0thenleading_zerosx-1elseleading_zeros(lognotx)-1letsigned_bitsizex=Sys.int_size-leading_sign_bitsx(* Number of trailing zeros. Hacker's Delight (2 ed.), algorithm 5.21 *)lettrailing_zerosx=ifx=0thenSys.int_sizeelsebeginletx=refxandn=ref(Sys.int_size-1)inifSys.int_size>32thenbeginlety=shift_left!x32inify<>0then(n:=!n-32;x:=y)end;lety=shift_left!x16inify<>0then(n:=!n-16;x:=y);lety=shift_left!x8inify<>0then(n:=!n-8;x:=y);lety=shift_left!x4inify<>0then(n:=!n-4;x:=y);lety=shift_left!x2inify<>0then(n:=!n-2;x:=y);lety=shift_left!x1inify<>0then!n-1else!nend(* Population count. Hacker's Delight (2 ed.), algorithm 5.2 *)externalint64_to_int:int64->int="%int64_to_int"letcst1=int64_to_int0x5555_5555_5555_5555Lletcst2=int64_to_int0x3333_3333_3333_3333Lletcst3=int64_to_int0x0F0F_0F0F_0F0F_0F0FLletpopcountx=letx=subx(logand(shift_right_logicalx1)cst1)inletx=add(logandxcst2)(logand(shift_right_logicalx2)cst2)inletx=logand(addx(shift_right_logicalx4))cst3inletx=addx(shift_right_logicalx8)inletx=addx(shift_right_logicalx16)inifSys.int_size>32thenbeginletx=addx(shift_right_logicalx32)inxland0x7Fendelsexland0x3Fexternalto_float:int->float="%floatofint"externalof_float:float->int="%intoffloat"(*
external int_of_string : string -> int = "caml_int_of_string"
let of_string s = try Some (int_of_string s) with Failure _ -> None
*)externalformat_int:string->int->string="caml_format_int"letto_stringx=format_int"%d"xexternalseeded_hash_param:int->int->int->'a->int="caml_hash"[@@noalloc]letseeded_hashseedx=seeded_hash_param10100seedxlethashx=seeded_hash_param101000x(* Floor division, ceil division *)letfdivnd=letq=divndiniflogxornd>=0(* n and d have same sign *)||n=q*dthenqelsepredqletcdivnd=letq=divndiniflogxornd<0(* n and d have different signs *)||n=q*dthenqelsesuccq(* Euclidean division and remainder *)leteremnd=letr=remndinifr>=0thenrelseifd>=0thenr+delser-dletedivnd=letq=divndinletr=n-q*dinifr>=0thenqelseifd>=0thenpredqelsesuccq