2
* ExtInt - Extended integers
3
* Copyright (C) 2007 Bluestorm <bluestorm dot dylc on-the-server gmail dot com>
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version,
10
* with the special exception on linking described in file LICENSE.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
TYPE_CONV_PATH "Batteries" (*For Sexplib, Bin-prot...*)
28
let current_value = ref min_int in
29
let already_through = ref false in
31
if !current_value = max_int then
32
if !already_through then raise Enum.No_more_elements
33
else ( already_through := true; max_int )
34
else Ref.post_incr current_value
37
module BaseInt = struct
39
type t = int with sexp
43
external neg : int -> int = "%negint"
44
external add : int -> int -> int = "%addint"
45
external sub : int -> int -> int = "%subint"
46
external mul : int -> int -> int = "%mulint"
47
external div : int -> int -> int = "%divint"
49
external ( + ) : int -> int -> int = "%addint"
50
external ( - ) : int -> int -> int = "%subint"
51
external ( * ) : int -> int -> int = "%mulint"
52
external ( / ) : int -> int -> int = "%divint"
54
external pred: int -> int = "%predint"
55
external succ: int -> int = "%succint"
58
external modulo : int -> int -> int = "%modint"
59
let pow = generic_pow ~zero ~one ~div_two:(fun n -> n / 2) ~mod_two:(fun n -> n mod 2) ~mul
61
let min_num, max_num = min_int, max_int
64
external of_int : int -> int = "%identity"
65
external to_int : int -> int = "%identity"
70
with Failure "int_of_string" -> raise (Invalid_argument "int_of_string")
71
let to_string = string_of_int
75
let minus_one = ( - 1)
77
external to_float : int -> float = "%floatofint"
78
external of_float : float -> int = "%intoffloat"
80
external of_string : string -> int = "caml_int_of_string"
82
external rem : int -> int -> int = "%modint"
84
let ( <> ) a b = a <> b
85
let ( <= ) a b = a <= b
86
let ( >= ) a b = a >= b
91
let ( ** ) a b = pow a b
93
let print out t = InnerIO.nwrite out (string_of_int t)
94
let t_printer paren out t = print out t
96
let ( -- ) x y = Enum.seq x (add one) ((>=) y)
99
else Enum.seq x pred ((<=) y)
105
let operations = let module N = Number.MakeNumeric(BaseInt) in N.operations
111
module BaseSafeInt = struct
115
Open this module and [SafeInt] to replace traditional integer operators with
116
their safe counterparts
123
let c = Pervasives.( + ) a b in
124
if a < 0 && b < 0 && c >= 0 || a > 0 && b > 0 && c <= 0 then raise Overflow
129
let c = Pervasives.( - ) a b in
130
if a < 0 && b > 0 && c >= 0 || a > 0 && b < 0 && c <= 0 then raise Overflow
132
let ( - ) a b = sub a b
135
if x <> min_int then ~- x
139
if x <> max_int then succ x
143
if x <> min_int then pred x
147
if x <> min_int then abs x
150
(*Here, we assume that, in case of overflow the result will be different when computing
151
in 31 bits (resp 63 bits) and in 32 bits (resp 64 bits). Need to check that trick.*)
154
else if (abs a) > max_int / (abs b) then raise Overflow else a * b
156
let pow = Number.generic_pow ~zero ~one ~div_two:(fun n -> n/2) ~mod_two:(fun n -> n mod 20) ~mul
160
module Safe_int = struct
162
let operations = let module N = Number.MakeNumeric(BaseSafeInt) in N.operations
168
module Numeric = struct include Numeric(BaseInt) end
171
module SafeInt = struct
173
module Numeric = struct include Numeric(BaseSafeInt) end