123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188(**************************************************************************)(* *)(* OCaml *)(* *)(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)(* *)(* Copyright 1996 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. *)(* *)(**************************************************************************)(* Module [Int32]: 32-bit integers *)externalneg:int32->int32="%int32_neg"externaladd:int32->int32->int32="%int32_add"externalsub:int32->int32->int32="%int32_sub"externalmul:int32->int32->int32="%int32_mul"externaldiv:int32->int32->int32="%int32_div"externalrem:int32->int32->int32="%int32_mod"externallogand:int32->int32->int32="%int32_and"externallogor:int32->int32->int32="%int32_or"externallogxor:int32->int32->int32="%int32_xor"externalshift_left:int32->int->int32="%int32_lsl"externalshift_right:int32->int->int32="%int32_asr"externalshift_right_logical:int32->int->int32="%int32_lsr"externalof_int:int->int32="%int32_of_int"externalto_int:int32->int="%int32_to_int"externalof_float:float->int32="caml_int32_of_float""caml_int32_of_float_unboxed"[@@unboxed][@@noalloc]externalto_float:int32->float="caml_int32_to_float""caml_int32_to_float_unboxed"[@@unboxed][@@noalloc]externalbits_of_float:float->int32="caml_int32_bits_of_float""caml_int32_bits_of_float_unboxed"[@@unboxed][@@noalloc]externalfloat_of_bits:int32->float="caml_int32_float_of_bits""caml_int32_float_of_bits_unboxed"[@@unboxed][@@noalloc]letzero=0lletone=1lletminus_one=-1lletsuccn=addn1lletpredn=subn1lletabsn=ifn>=0lthennelsenegnletmin_int=0x80000000lletmax_int=0x7FFFFFFFlletlognotn=logxorn(-1l)letunsigned_to_int=matchSys.word_sizewith|32->letmax_int=of_intStdlib.max_intinfunn->ifn>=0l&&n<=max_intthenSome(to_intn)elseNone|64->(* So that it compiles in 32-bit *)letmask=0xFFFFlsl16lor0xFFFFinfunn->Some(to_intnlandmask)|_->assertfalseexternalformat:string->int32->string="caml_int32_format"letto_stringn=format"%d"nexternalof_string:string->int32="caml_int32_of_string"letof_string_opts=trySome(of_strings)withFailure_->Nonetypet=int32letcompare(x:t)(y:t)=Stdlib.comparexyletequal(x:t)(y:t)=x=yletunsigned_comparenm=compare(subnmin_int)(submmin_int)letunsigned_ltnm=subnmin_int<submmin_intletminxy:t=ifx<=ythenxelseyletmaxxy:t=ifx>=ythenxelsey(* Unsigned division from signed division of the same bitness.
See Warren Jr., Henry S. (2013). Hacker's Delight (2 ed.), Sec 9-3.
*)letunsigned_divnd=ifd<zerothenifunsigned_ltndthenzeroelseoneelseletq=shift_left(div(shift_right_logicaln1)d)1inletr=subn(mulqd)inifunsigned_ltrdthenqelsesuccqletunsigned_remnd=subn(mul(unsigned_divnd)d)(* Floor division, ceil division *)letfdivnd=letq=divndiniflogxornd>=0l(* n and d have same sign *)||n=mulqdthenqelsepredqletcdivnd=letq=divndiniflogxornd<0l(* n and d have different signs *)||n=mulqdthenqelsesuccq(* Euclidean division and remainder *)leteremnd=letr=remndinifr>=0lthenrelseifd>=0lthenaddrdelsesubrdletedivnd=letq=divndinletr=subn(mulqd)inifr>=0lthenqelseifd>=0lthenpredqelsesuccq(* Number of leading zeros. Hacker's Delight (2 ed.), algorithm 5.12 *)letleading_zerosx=letx=refxandn=ref32inlety=shift_right_logical!x16inify<>0lthen(n:=!n-16;x:=y);lety=shift_right_logical!x8inify<>0lthen(n:=!n-8;x:=y);lety=shift_right_logical!x4inify<>0lthen(n:=!n-4;x:=y);lety=shift_right_logical!x2inify<>0lthen(n:=!n-2;x:=y);lety=shift_right_logical!x1inify<>0lthen!n-2else!n-to_int!xletunsigned_bitsizex=32-leading_zerosx(* Number of leading sign bits. *)letleading_sign_bitsx=ifx>=0lthenleading_zerosx-1elseleading_zeros(lognotx)-1letsigned_bitsizex=32-leading_sign_bitsx(* Number of trailing zeros. Hacker's Delight (2 ed.), algorithm 5.21 *)lettrailing_zerosx=ifx=0lthen32elsebeginletx=refxandn=ref31inlety=shift_left!x16inify<>0lthen(n:=!n-16;x:=y);lety=shift_left!x8inify<>0lthen(n:=!n-8;x:=y);lety=shift_left!x4inify<>0lthen(n:=!n-4;x:=y);lety=shift_left!x2inify<>0lthen(n:=!n-2;x:=y);lety=shift_left!x1inify<>0lthen!n-1else!nend(* Population count. Hacker's Delight (2 ed.), algorithm 5.2 *)letpopcountx=letx=subx(logand(shift_right_logicalx1)0x5555_5555l)inletx=add(logandx0x3333_3333l)(logand(shift_right_logicalx2)0x3333_3333l)inletx=logand(addx(shift_right_logicalx4))0x0F0F_0F0Flinletx=addx(shift_right_logicalx8)inletx=addx(shift_right_logicalx16)into_intxland0x3Fexternalseeded_hash_param:int->int->int->'a->int="caml_hash"[@@noalloc]letseeded_hashseedx=seeded_hash_param10100seedxlethashx=seeded_hash_param101000x