ocaml/utils/nativeint.ml

64 lines
2.1 KiB
OCaml

(***********************************************************************)
(* *)
(* Objective Caml *)
(* *)
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 1996 Institut National de Recherche en Informatique et *)
(* Automatique. Distributed only by permission. *)
(* *)
(***********************************************************************)
(* $Id$ *)
(* lsb is the least significant bit of the native int (0 <= lsb <= 1)
msw is the remaining 31 or 63 most significant bits. *)
type t = { msw: int; lsb: int }
let from i = { msw = i asr 1; lsb = i land 1 }
let to_int n = (n.msw lsl 1) lor n.lsb
let add n1 n2 =
let s = n1.lsb + n2.lsb in
{ msw = n1.msw + n2.msw + s asr 1; lsb = s land 1 }
let sub n1 n2 =
let d = n1.lsb - n2.lsb in
{ msw = n1.msw - n2.msw + d asr 1; lsb = d land 1 }
let shift n s =
if s = 0 then n else
if s > 0 then
{ msw = (n.msw lsl s) lor (n.lsb lsl (s-1)); lsb = 0 }
else
{ msw = n.msw asr (-s); lsb = (n.msw asr (-s - 1)) land 1 }
let sign n =
if n.msw < 0 then -1 else
if n.msw = 0 && n.lsb = 0 then 0 else 1
let compare n1 n2 = sign(sub n1 n2)
let cmp n1 i2 = compare n1 (from i2)
let to_string n =
let a = if n.msw >= 0 then n else sub (from 0) n in
let (q, r) =
(* Watch out for the case n.msw = min_int, in which case a.msw < 0 *)
if a.msw <> min_int
then (a.msw / 5, a.msw mod 5)
else (max_int / 5, max_int mod 5 + 1) in
(if n.msw >= 0 then "" else "-") ^
(if q > 0 then string_of_int q else "") ^
string_of_int (r * 2 + a.lsb)
let to_hexa_string n =
let a = if n.msw >= 0 then n else sub (from 0) n in
let q = a.msw lsr 3 in
let r = a.msw land 0x7 in
Printf.sprintf "%s0x%x%x"
(if n.msw >= 0 then "" else "-")
q
(r * 2 + a.lsb)