This commit is contained in:
swrup 2025-11-11 02:07:51 +01:00
parent aa2ff7b2f0
commit 2f3113f55d
11742 changed files with 1223940 additions and 0 deletions

View file

@ -0,0 +1,198 @@
(* stress test, using random and corner cases
compares Big_int_Z, a Big_int compatible interface for Z, to OCaml's
reference Big_int library
This file is part of the Zarith library
http://forge.ocamlcore.org/projects/zarith .
It is distributed under LGPL 2 licensing, with static linking exception.
See the LICENSE file included in the distribution.
Copyright (c) 2010-2011 Antoine Miné, Abstraction project.
Abstraction is part of the LIENS (Laboratoire d'Informatique de l'ENS),
a joint laboratory by:
CNRS (Centre national de la recherche scientifique, France),
ENS (École normale supérieure, Paris, France),
INRIA Rocquencourt (Institut national de recherche en informatique, France).
*)
module B = Big_int (* reference library *)
module T = Big_int_Z (* tested library *)
(* randomness *)
let _ = Random.init 42
let random_int64 () =
let a,b,c = Random.bits(), Random.bits(), Random.bits () in
let a,b,c = Int64.of_int a, Int64.of_int b, Int64.of_int c in
let a,b,c = Int64.shift_left a 60, Int64.shift_left b 30, c in
Int64.logor a (Int64.logor b c)
let random_int () = Int64.to_int (random_int64 ())
let random_string () =
let l = 1 + Random.int 200 in
let s = Buffer.create l in
let st = if l > 1 && Random.bool () then begin
Buffer.add_char s '-';
1
end else 0 in
for i = st to l - 1 do
Buffer.add_char s (Char.chr (48 + Random.int 10))
done;
Buffer.contents s
(* list utility *)
let list_make n f =
let rec doit i acc = if i < 0 then acc else doit (i-1) ((f i)::acc) in
doit (n-1) []
(* interesting numbers, as big_int *)
let p = (list_make 128 (B.shift_left_big_int B.unit_big_int))
let pn = p @ (List.map B.minus_big_int p)
let g_list =
[B.zero_big_int] @
pn @ (List.map B.succ_big_int pn) @ (List.map B.pred_big_int pn) @
(list_make 128 (fun _ -> B.big_int_of_int (random_int ()))) @
(list_make 128 (fun _ -> B.big_int_of_string (random_string())))
let sh_list = list_make 256 (fun x -> x)
let pow_list = [1;2;3;4;5;6;7;8;9;10;20;55]
(* conversion to Z *)
let g_t_list =
Printf.printf "converting %i numbers\n%!" (List.length g_list);
List.map
(fun g ->
let t = T.big_int_of_string (B.string_of_big_int g) in
let g' = B.big_int_of_string (T.string_of_big_int t) in
if B.compare_big_int g g' <> 0 then failwith (Printf.sprintf "string_of_big_int failure: %s" (B.string_of_big_int g));
g, t
)
g_list
let rec cut_list n l =
if n <= 0 then [] else match l with [] -> [] | h :: t -> h :: cut_list (n-1) t
let small_g_t_list = cut_list 256 g_t_list
(* operator tests *)
let test_un msg filt gf tf =
Printf.printf "testing %s on %i numbers\n%!" msg (List.length g_t_list);
List.iter
(fun (g,t) ->
try
if filt g then (
let g' = gf g and t' = tf t in
if B.string_of_big_int g' <> T.string_of_big_int t' then failwith (Printf.sprintf "%s failure: arg=%s Bresult=%s Tresult=%s" msg (B.string_of_big_int g) (B.string_of_big_int g') (T.string_of_big_int t'))
)
with Failure _ -> ()
) g_t_list
let test_bin_gen msg filt gf tf l =
Printf.printf "testing %s on %i x %i numbers\n%!" msg (List.length l) (List.length l);
List.iter
(fun (g1,t1) ->
List.iter
(fun (g2,t2) ->
if filt (g1,g2) then (
let g' = gf g1 g2 and t' = tf t1 t2 in
if B.string_of_big_int g' <> T.string_of_big_int t' then failwith (Printf.sprintf "%s failure: arg1=%s arg2=%s Bresult=%s Tresult=%s" msg (B.string_of_big_int g1) (B.string_of_big_int g2) (B.string_of_big_int g') (T.string_of_big_int t'))
)
) l
) l
let test_bin msg filt gf tf = test_bin_gen msg filt gf tf g_t_list
let test_bin_small msg filt gf tf = test_bin_gen msg filt gf tf small_g_t_list
let test_shift msg gf tf =
Printf.printf "testing %s on %i numbers\n%!" msg (List.length g_t_list);
List.iter
(fun s ->
List.iter
(fun (g,t) ->
let g' = gf g s and t' = tf t s in
if B.string_of_big_int g' <> T.string_of_big_int t' then failwith (Printf.sprintf "%s failure: arg1=%s arg2=%i Bresult=%s Tresult=%s" msg (B.string_of_big_int g) s (B.string_of_big_int g') (T.string_of_big_int t'))
) g_t_list
) sh_list
let test_pow msg gf tf =
Printf.printf "testing %s on %i numbers\n%!" msg (List.length g_t_list);
List.iter
(fun s ->
List.iter
(fun (g,t) ->
let g' = gf g s and t' = tf t s in
if B.string_of_big_int g' <> T.string_of_big_int t' then failwith (Printf.sprintf "%s failure: arg1=%s arg2=%i Bresult=%s Tresult=%s" msg (B.string_of_big_int g) s (B.string_of_big_int g') (T.string_of_big_int t'))
) g_t_list
) pow_list
let test_comparison msg gf tf l =
Printf.printf "testing %s on %i x %i numbers\n%!" msg (List.length l) (List.length l);
List.iter
(fun (g1,t1) ->
List.iter
(fun (g2,t2) ->
let g' = gf g1 g2 and t' = tf t1 t2 in
if g' <> t' then failwith (Printf.sprintf "%s failure: arg1=%s arg2=%s" msg (B.string_of_big_int g1) (B.string_of_big_int g2))
) l
) l
let filt_none _ = true
let filt_pos x = B.sign_big_int x >= 0
let filt_nonzero2 (_,d) = B.sign_big_int d <> 0
let filt_pos2 (x,y) = B.sign_big_int x >= 0 && B.sign_big_int y >= 0
let filt_nonzero22 (x,y) = B.sign_big_int x <> 0 && B.sign_big_int y <> 0
let ffst f x = fst (f x)
let fsnd f x = snd (f x)
let ffst2 f x y = fst (f x y)
let fsnd2 f x y = snd (f x y)
let _ = test_un "int_of_big_int" filt_none (fun x -> x) (fun x -> T.big_int_of_int (T.int_of_big_int x))
let _ = test_un "int32_of_big_int" filt_none (fun x -> x) (fun x -> T.big_int_of_int32 (T.int32_of_big_int x))
let _ = test_un "int64_of_big_int" filt_none (fun x -> x) (fun x -> T.big_int_of_int64 (T.int64_of_big_int x))
let _ = test_un "nativeint_of_big_int" filt_none (fun x -> x) (fun x -> T.big_int_of_nativeint (T.nativeint_of_big_int x))
let _ = test_un "string_of_big_int" filt_none (fun x -> x) (fun x -> T.big_int_of_string (T.string_of_big_int x))
let _ = test_un "minus_big_int" filt_none B.minus_big_int T.minus_big_int
let _ = test_un "abs_big_int" filt_none B.abs_big_int T.abs_big_int
let _ = test_un "succ_big_int"filt_none B.succ_big_int T.succ_big_int
let _ = test_un "pred_big_int" filt_none B.pred_big_int T.pred_big_int
let _ = test_un "sqrt_big_int" filt_pos B.sqrt_big_int T.sqrt_big_int
let _ = test_bin "add_big_int" filt_none B.add_big_int T.add_big_int
let _ = test_bin "sub_big_int" filt_none B.sub_big_int T.sub_big_int
let _ = test_bin "mult_big_int" filt_none B.mult_big_int T.mult_big_int
let _ = test_bin_small "div_big_int" filt_nonzero2 B.div_big_int T.div_big_int
let _ = test_bin_small "quomod_big_int #1" filt_nonzero2 (ffst2 B.quomod_big_int) (ffst2 T.quomod_big_int)
let _ = test_bin_small "quomod_big_int #2" filt_nonzero2 (fsnd2 B.quomod_big_int) (fsnd2 T.quomod_big_int)
let _ = test_bin_small "mod_big_int" filt_nonzero2 B.mod_big_int T.mod_big_int
let _ = test_bin_small "gcd_big_int" filt_nonzero22 B.gcd_big_int T.gcd_big_int
let _ = test_bin "and_big_int" filt_pos2 B.and_big_int T.and_big_int
let _ = test_bin "or_big_int" filt_pos2 B.or_big_int T.or_big_int
let _ = test_bin "xor_big_int" filt_pos2 B.xor_big_int T.xor_big_int
let _ = test_shift "shift_left_big_int" B.shift_left_big_int T.shift_left_big_int
let _ = test_shift "shift_right_big_int" B.shift_right_big_int T.shift_right_big_int
let _ = test_shift "shift_right_towards_zero_big_int" B.shift_right_towards_zero_big_int T.shift_right_towards_zero_big_int
let _ = test_pow "power_big_int_positive_int" B.power_big_int_positive_int T.power_big_int_positive_int
let _ = test_comparison "compare" B.compare_big_int Z.compare g_t_list
let _ = test_comparison "equal" B.eq_big_int Z.equal g_t_list
let _ = test_comparison "lt" B.lt_big_int (fun x y -> x < y) g_t_list
let _ = test_comparison "ge" B.ge_big_int (fun x y -> x >= y) g_t_list
let _ = Printf.printf "All tests passed!\n"

View file

@ -0,0 +1,60 @@
(* Accumulate [n] samples from function [f] and check the chi-square.
Assumes [f] returns integers in the [0..255] range. *)
let chisquare n f =
let r = 256 in
let freq = Array.make r 0 in
for i = 0 to n - 1 do
let t = f () in freq.(t) <- freq.(t) + 1
done;
let expected = float n /. float r in
let t =
Array.fold_left
(fun s x -> let d = float x -. expected in d *. d +. s)
0.0 freq in
let chi2 = t /. expected in
let degfree = float r -. 1.0 in
(* The degree of freedom is high, so we approximate as a normal
distribution with mean equal to degfree and variance 2 * degfree.
Four sigmas correspond to a 99.9968% confidence interval.
(Without the approximation, the confidence interval seems to be 99.986%.)
*)
chi2 <= degfree +. 4.0 *. sqrt (2.0 *. degfree)
let failed = ref false
let test_base name f =
if not (chisquare 100_000 f) then begin
Printf.printf "%s: suspicious result\n%!" name;
failed := true
end
let test name f =
(* Test the low 8 bits of the result of f *)
test_base name (fun () -> Z.to_int (Z.logand (f ()) (Z.of_int 0xFF)))
let p = Z.of_string "35742549198872617291353508656626642567"
let _ =
test "random_bits 15 (bits 0-7)"
(fun () -> Z.random_bits 15);
test "random_bits 32 (bits 12-19)"
(fun () -> Z.(shift_right (random_bits 32) 12));
test "random_bits 31 (bits 23-30)"
(fun () -> Z.(shift_right (random_bits 31) 23));
test "random_int 2^30 (bits 0-7)"
(fun () -> Z.(random_int (shift_left one 30)));
test "random_int 2^30 (bits 21-28)"
(fun () -> Z.(shift_right (random_int (shift_left one 30)) 21));
test "random_int (256 * p) / p"
(let bound = Z.shift_left p 8 in
fun () -> Z.(div (random_int bound) p));
(* Also test our hash function, why not? *)
test_base "hash (random_int p) (bits 0-7)"
(fun () -> Z.(hash (random_int p)) land 0xFF);
test_base "hash (random_int p) (bits 16-23)"
(fun () -> (Z.(hash (random_int p)) lsr 16) land 0xFF);
exit (if !failed then 2 else 0)

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,14 @@
(* Marshal some interesting big integers to the given file *)
let _ =
let file = Sys.argv.(1) in
let oc = open_out_bin file in
for nbits = 16 to 128 do
let x = Z.shift_left Z.one nbits in
output_value oc (Z.pred (Z.neg x));
output_value oc (Z.neg x);
output_value oc (Z.pred x);
output_value oc x
done;
close_out oc

View file

@ -0,0 +1,24 @@
(* Unmarshal big integers from the given file, and report errors *)
open Printf
let expect ic n =
try
let m = (input_value ic : Z.t) in
if Z.equal m n then printf " OK" else printf " Wrong"
with Failure _ ->
printf " Fail"
let _ =
let file = Sys.argv.(1) in
let ic = open_in_bin file in
for nbits = 16 to 128 do
printf "%d:" nbits;
let x = Z.shift_left Z.one nbits in
expect ic (Z.pred (Z.neg x));
expect ic (Z.neg x);
expect ic (Z.pred x);
expect ic x;
print_newline()
done;
close_in ic

View file

@ -0,0 +1,113 @@
16: OK OK OK OK
17: OK OK OK OK
18: OK OK OK OK
19: OK OK OK OK
20: OK OK OK OK
21: OK OK OK OK
22: OK OK OK OK
23: OK OK OK OK
24: OK OK OK OK
25: OK OK OK OK
26: OK OK OK OK
27: OK OK OK OK
28: OK OK OK OK
29: OK OK OK OK
30: OK OK OK OK
31: OK OK OK OK
32: OK OK OK OK
33: OK OK OK OK
34: OK OK OK OK
35: OK OK OK OK
36: OK OK OK OK
37: OK OK OK OK
38: OK OK OK OK
39: OK OK OK OK
40: OK OK OK OK
41: OK OK OK OK
42: OK OK OK OK
43: OK OK OK OK
44: OK OK OK OK
45: OK OK OK OK
46: OK OK OK OK
47: OK OK OK OK
48: OK OK OK OK
49: OK OK OK OK
50: OK OK OK OK
51: OK OK OK OK
52: OK OK OK OK
53: OK OK OK OK
54: OK OK OK OK
55: OK OK OK OK
56: OK OK OK OK
57: OK OK OK OK
58: OK OK OK OK
59: OK OK OK OK
60: OK OK OK OK
61: OK OK OK OK
62: OK OK OK OK
63: OK OK OK OK
64: OK OK OK OK
65: OK OK OK OK
66: OK OK OK OK
67: OK OK OK OK
68: OK OK OK OK
69: OK OK OK OK
70: OK OK OK OK
71: OK OK OK OK
72: OK OK OK OK
73: OK OK OK OK
74: OK OK OK OK
75: OK OK OK OK
76: OK OK OK OK
77: OK OK OK OK
78: OK OK OK OK
79: OK OK OK OK
80: OK OK OK OK
81: OK OK OK OK
82: OK OK OK OK
83: OK OK OK OK
84: OK OK OK OK
85: OK OK OK OK
86: OK OK OK OK
87: OK OK OK OK
88: OK OK OK OK
89: OK OK OK OK
90: OK OK OK OK
91: OK OK OK OK
92: OK OK OK OK
93: OK OK OK OK
94: OK OK OK OK
95: OK OK OK OK
96: OK OK OK OK
97: OK OK OK OK
98: OK OK OK OK
99: OK OK OK OK
100: OK OK OK OK
101: OK OK OK OK
102: OK OK OK OK
103: OK OK OK OK
104: OK OK OK OK
105: OK OK OK OK
106: OK OK OK OK
107: OK OK OK OK
108: OK OK OK OK
109: OK OK OK OK
110: OK OK OK OK
111: OK OK OK OK
112: OK OK OK OK
113: OK OK OK OK
114: OK OK OK OK
115: OK OK OK OK
116: OK OK OK OK
117: OK OK OK OK
118: OK OK OK OK
119: OK OK OK OK
120: OK OK OK OK
121: OK OK OK OK
122: OK OK OK OK
123: OK OK OK OK
124: OK OK OK OK
125: OK OK OK OK
126: OK OK OK OK
127: OK OK OK OK
128: OK OK OK OK

View file

@ -0,0 +1,113 @@
16: OK OK OK OK
17: OK OK OK OK
18: OK OK OK OK
19: OK OK OK OK
20: OK OK OK OK
21: OK OK OK OK
22: OK OK OK OK
23: OK OK OK OK
24: OK OK OK OK
25: OK OK OK OK
26: OK OK OK OK
27: OK OK OK OK
28: OK OK OK OK
29: OK OK OK OK
30: Fail OK OK Fail
31: Fail Fail Fail Fail
32: Fail Fail Fail Fail
33: Fail Fail Fail Fail
34: Fail Fail Fail Fail
35: Fail Fail Fail Fail
36: Fail Fail Fail Fail
37: Fail Fail Fail Fail
38: Fail Fail Fail Fail
39: Fail Fail Fail Fail
40: Fail Fail Fail Fail
41: Fail Fail Fail Fail
42: Fail Fail Fail Fail
43: Fail Fail Fail Fail
44: Fail Fail Fail Fail
45: Fail Fail Fail Fail
46: Fail Fail Fail Fail
47: Fail Fail Fail Fail
48: Fail Fail Fail Fail
49: Fail Fail Fail Fail
50: Fail Fail Fail Fail
51: Fail Fail Fail Fail
52: Fail Fail Fail Fail
53: Fail Fail Fail Fail
54: Fail Fail Fail Fail
55: Fail Fail Fail Fail
56: Fail Fail Fail Fail
57: Fail Fail Fail Fail
58: Fail Fail Fail Fail
59: Fail Fail Fail Fail
60: Fail Fail Fail Fail
61: Fail Fail Fail Fail
62: OK Fail Fail OK
63: OK OK OK OK
64: OK OK OK OK
65: OK OK OK OK
66: OK OK OK OK
67: OK OK OK OK
68: OK OK OK OK
69: OK OK OK OK
70: OK OK OK OK
71: OK OK OK OK
72: OK OK OK OK
73: OK OK OK OK
74: OK OK OK OK
75: OK OK OK OK
76: OK OK OK OK
77: OK OK OK OK
78: OK OK OK OK
79: OK OK OK OK
80: OK OK OK OK
81: OK OK OK OK
82: OK OK OK OK
83: OK OK OK OK
84: OK OK OK OK
85: OK OK OK OK
86: OK OK OK OK
87: OK OK OK OK
88: OK OK OK OK
89: OK OK OK OK
90: OK OK OK OK
91: OK OK OK OK
92: OK OK OK OK
93: OK OK OK OK
94: OK OK OK OK
95: OK OK OK OK
96: OK OK OK OK
97: OK OK OK OK
98: OK OK OK OK
99: OK OK OK OK
100: OK OK OK OK
101: OK OK OK OK
102: OK OK OK OK
103: OK OK OK OK
104: OK OK OK OK
105: OK OK OK OK
106: OK OK OK OK
107: OK OK OK OK
108: OK OK OK OK
109: OK OK OK OK
110: OK OK OK OK
111: OK OK OK OK
112: OK OK OK OK
113: OK OK OK OK
114: OK OK OK OK
115: OK OK OK OK
116: OK OK OK OK
117: OK OK OK OK
118: OK OK OK OK
119: OK OK OK OK
120: OK OK OK OK
121: OK OK OK OK
122: OK OK OK OK
123: OK OK OK OK
124: OK OK OK OK
125: OK OK OK OK
126: OK OK OK OK
127: OK OK OK OK
128: OK OK OK OK

View file

@ -0,0 +1,113 @@
16: OK OK OK OK
17: OK OK OK OK
18: OK OK OK OK
19: OK OK OK OK
20: OK OK OK OK
21: OK OK OK OK
22: OK OK OK OK
23: OK OK OK OK
24: OK OK OK OK
25: OK OK OK OK
26: OK OK OK OK
27: OK OK OK OK
28: OK OK OK OK
29: OK OK OK OK
30: Fail OK OK Fail
31: Fail Fail Fail Fail
32: Fail Fail Fail Fail
33: Fail Fail Fail Fail
34: Fail Fail Fail Fail
35: Fail Fail Fail Fail
36: Fail Fail Fail Fail
37: Fail Fail Fail Fail
38: Fail Fail Fail Fail
39: Fail Fail Fail Fail
40: Fail Fail Fail Fail
41: Fail Fail Fail Fail
42: Fail Fail Fail Fail
43: Fail Fail Fail Fail
44: Fail Fail Fail Fail
45: Fail Fail Fail Fail
46: Fail Fail Fail Fail
47: Fail Fail Fail Fail
48: Fail Fail Fail Fail
49: Fail Fail Fail Fail
50: Fail Fail Fail Fail
51: Fail Fail Fail Fail
52: Fail Fail Fail Fail
53: Fail Fail Fail Fail
54: Fail Fail Fail Fail
55: Fail Fail Fail Fail
56: Fail Fail Fail Fail
57: Fail Fail Fail Fail
58: Fail Fail Fail Fail
59: Fail Fail Fail Fail
60: Fail Fail Fail Fail
61: Fail Fail Fail Fail
62: OK Fail Fail OK
63: OK OK OK OK
64: OK OK OK OK
65: OK OK OK OK
66: OK OK OK OK
67: OK OK OK OK
68: OK OK OK OK
69: OK OK OK OK
70: OK OK OK OK
71: OK OK OK OK
72: OK OK OK OK
73: OK OK OK OK
74: OK OK OK OK
75: OK OK OK OK
76: OK OK OK OK
77: OK OK OK OK
78: OK OK OK OK
79: OK OK OK OK
80: OK OK OK OK
81: OK OK OK OK
82: OK OK OK OK
83: OK OK OK OK
84: OK OK OK OK
85: OK OK OK OK
86: OK OK OK OK
87: OK OK OK OK
88: OK OK OK OK
89: OK OK OK OK
90: OK OK OK OK
91: OK OK OK OK
92: OK OK OK OK
93: OK OK OK OK
94: OK OK OK OK
95: OK OK OK OK
96: OK OK OK OK
97: OK OK OK OK
98: OK OK OK OK
99: OK OK OK OK
100: OK OK OK OK
101: OK OK OK OK
102: OK OK OK OK
103: OK OK OK OK
104: OK OK OK OK
105: OK OK OK OK
106: OK OK OK OK
107: OK OK OK OK
108: OK OK OK OK
109: OK OK OK OK
110: OK OK OK OK
111: OK OK OK OK
112: OK OK OK OK
113: OK OK OK OK
114: OK OK OK OK
115: OK OK OK OK
116: OK OK OK OK
117: OK OK OK OK
118: OK OK OK OK
119: OK OK OK OK
120: OK OK OK OK
121: OK OK OK OK
122: OK OK OK OK
123: OK OK OK OK
124: OK OK OK OK
125: OK OK OK OK
126: OK OK OK OK
127: OK OK OK OK
128: OK OK OK OK

View file

@ -0,0 +1,113 @@
16: OK OK OK OK
17: OK OK OK OK
18: OK OK OK OK
19: OK OK OK OK
20: OK OK OK OK
21: OK OK OK OK
22: OK OK OK OK
23: OK OK OK OK
24: OK OK OK OK
25: OK OK OK OK
26: OK OK OK OK
27: OK OK OK OK
28: OK OK OK OK
29: OK OK OK OK
30: OK OK OK OK
31: OK OK OK OK
32: OK OK OK OK
33: OK OK OK OK
34: OK OK OK OK
35: OK OK OK OK
36: OK OK OK OK
37: OK OK OK OK
38: OK OK OK OK
39: OK OK OK OK
40: OK OK OK OK
41: OK OK OK OK
42: OK OK OK OK
43: OK OK OK OK
44: OK OK OK OK
45: OK OK OK OK
46: OK OK OK OK
47: OK OK OK OK
48: OK OK OK OK
49: OK OK OK OK
50: OK OK OK OK
51: OK OK OK OK
52: OK OK OK OK
53: OK OK OK OK
54: OK OK OK OK
55: OK OK OK OK
56: OK OK OK OK
57: OK OK OK OK
58: OK OK OK OK
59: OK OK OK OK
60: OK OK OK OK
61: OK OK OK OK
62: OK OK OK OK
63: OK OK OK OK
64: OK OK OK OK
65: OK OK OK OK
66: OK OK OK OK
67: OK OK OK OK
68: OK OK OK OK
69: OK OK OK OK
70: OK OK OK OK
71: OK OK OK OK
72: OK OK OK OK
73: OK OK OK OK
74: OK OK OK OK
75: OK OK OK OK
76: OK OK OK OK
77: OK OK OK OK
78: OK OK OK OK
79: OK OK OK OK
80: OK OK OK OK
81: OK OK OK OK
82: OK OK OK OK
83: OK OK OK OK
84: OK OK OK OK
85: OK OK OK OK
86: OK OK OK OK
87: OK OK OK OK
88: OK OK OK OK
89: OK OK OK OK
90: OK OK OK OK
91: OK OK OK OK
92: OK OK OK OK
93: OK OK OK OK
94: OK OK OK OK
95: OK OK OK OK
96: OK OK OK OK
97: OK OK OK OK
98: OK OK OK OK
99: OK OK OK OK
100: OK OK OK OK
101: OK OK OK OK
102: OK OK OK OK
103: OK OK OK OK
104: OK OK OK OK
105: OK OK OK OK
106: OK OK OK OK
107: OK OK OK OK
108: OK OK OK OK
109: OK OK OK OK
110: OK OK OK OK
111: OK OK OK OK
112: OK OK OK OK
113: OK OK OK OK
114: OK OK OK OK
115: OK OK OK OK
116: OK OK OK OK
117: OK OK OK OK
118: OK OK OK OK
119: OK OK OK OK
120: OK OK OK OK
121: OK OK OK OK
122: OK OK OK OK
123: OK OK OK OK
124: OK OK OK OK
125: OK OK OK OK
126: OK OK OK OK
127: OK OK OK OK
128: OK OK OK OK

View file

@ -0,0 +1,292 @@
let pow2 n =
let rec doit acc n =
if n<=0 then acc else doit (Z.add acc acc) (n-1)
in
doit Z.one n
let p30 = pow2 30
let p62 = pow2 62
let p300 = pow2 300
let p120 = pow2 120
let p121 = pow2 121
let test_of_string_Z () =
let round_trip_Z () =
let round_trip fmt x=
(Z.equal (Z.of_string (Z.format fmt x)) x)
in
let formats = [
"%i"; "%#b"; "%#o"; "%#x"; "%#X";
"%+i"; "%#+b"; "%#+o"; "%#+x"; "%#+X";
"%+0i"; "%#+0b"; "%#+0o"; "%#+0x"; "%#+0X";
] in
let numbers =
let (+) = Z.add in
let l = [p30; p62; p30 + p62; p300; p120; p121] in
l @ (List.map Z.neg l)
in
List.iter
(fun fmt ->
assert
(
List.for_all
(fun x -> round_trip fmt x)
numbers
)
)
formats
in
let fail d f x =
try
ignore (f x);
Printf.printf "%s should fail on %s\n" d x
with _ -> ()
in
let succ d f x y =
try
let z = f x in
if Z.equal z y
then ()
else
Printf.printf
"%s(%s) returned %s, expected %s\n"
d
x
(Z.to_string z)
(Z.to_string y)
with _ ->
Printf.printf "%s failed. Expected %s\n" d (Z.to_string y)
in
let z_and_int_agree s =
let f = try Some (int_of_string s) with _ -> None in
let z = try Some (Z.of_string s) with _ -> None in
match f,z with
| None, None -> ()
| Some i, Some z ->
if not (Z.equal (Z.of_int i) z)
then
Printf.printf
"Z.of_string (%s) returned %s, expected %s\n"
s
(Z.to_string z)
(string_of_int i)
| Some i, None ->
Printf.printf
"Z.of_string (%s) failed, expected %s\n"
s
(string_of_int i)
| None, Some z ->
Printf.printf
"Z.of_string (%s) returned %s, failure expected"
s
(Z.to_string z)
in
round_trip_Z ();
fail "Z.of_string" Z.of_string "0b2";
fail "Z.of_string" Z.of_string "0o8";
fail "Z.of_string" Z.of_string "0xg";
fail "Z.of_string" Z.of_string "0xG";
fail "Z.of_string" Z.of_string "0A";
succ "Z.of_string" Z.of_string "" Z.zero;
succ "Z.of_string" Z.of_string "+" Z.zero;
succ "Z.of_string" Z.of_string "-" Z.zero;
succ "Z.of_string" Z.of_string "0x" Z.zero;
succ "Z.of_string" Z.of_string "0b" Z.zero;
fail "Z.of_substring" (Z.of_substring ~pos:1 ~len:2) "0b2";
fail "Z.of_substring" (Z.of_substring ~pos:1 ~len:2) "0o8";
fail "Z.of_substring" (Z.of_substring ~pos:1 ~len:2) "0xg";
fail "Z.of_substring" (Z.of_substring ~pos:1 ~len:2) "0xG";
fail "Z.of_substring" (Z.of_substring ~pos:1 ~len:1) "0A";
succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:0) "+" Z.zero;
succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:1) "-+" Z.zero;
succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:2)"--1-" (Z.minus_one);
succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:2)"--1\000" (Z.minus_one);
succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:2)"\000-1\000" (Z.minus_one);
succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:1)"00b1" Z.zero;
succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:2)"00b1" Z.zero;
succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:3)"00b1" Z.one;
z_and_int_agree "_123";
z_and_int_agree "1_23";
z_and_int_agree "12_3";
z_and_int_agree "123_";
z_and_int_agree "0x_123";
z_and_int_agree "0_123";
let s = Z.format "%#b" p120 in
let n = String.length s in
for i = 0 to n - 3 do
succ "Z.of_substring"
(Z.of_substring ~pos:0 ~len:(n - i))
s
(Z.shift_right p120 i)
done
let _ = test_of_string_Z ()
let test_of_string_Q () =
let round_trip_Q () =
let round_trip fmt x=
let os = Q.of_string (Z.to_string x) in
let ob = Q.of_bigint x in
if Q.equal os ob then
true
else begin
Format.printf "%a not equal to %a\n" Q.pp_print os Q.pp_print ob;
false
end
in
let formats = [
"%i"; "%#b"; "%#o"; "%#x"; "%#X";
"%+i"; "%#+b"; "%#+o"; "%#+x"; "%#+X";
"%+0i"; "%#+0b"; "%#+0o"; "%#+0x"; "%#+0X";
] in
let numbers =
let (+) = Z.add in
let l = [p30; p62; p30 + p62; p300; p120; p121] in
(l @ (List.map Z.neg l))
in
List.iter
(fun fmt ->
assert
(
List.for_all
(fun x -> round_trip fmt x)
numbers
)
)
formats
in
let fail d f x =
try
let s = f x in
Printf.printf "%s should fail on %s. Got %s\n" d x (Q.to_string s)
with _ -> ()
in
let succ d f x y =
try
let z = f x in
if Q.equal z y
then ()
else
Printf.printf
"%s(%s) returned %s, expected %s\n"
d
x
(Q.to_string z)
(Q.to_string y)
with exc ->
Printf.printf "%s failed. Expected %s. Got %s\n" d (Q.to_string y)
(Printexc.to_string exc)
in
let q_and_float_agree s =
let f = try Some (float_of_string s) with _ -> None in
let q = try Some (Q.of_string s) with _ -> None in
match f,q with
| None, None -> ()
| Some f, Some q ->
if not ((Q.to_float q) = f)
then
Printf.printf
"Q.of_string (%s) returned %s, expected %s\n"
s
(Q.to_string q)
(string_of_float f)
| Some f, None ->
Printf.printf
"Q.of_string (%s) failed, expected %s\n"
s
(string_of_float f)
| None, Some q ->
Printf.printf
"Q.of_string (%s) returned %s, failure expected"
s
(Q.to_string q)
in
round_trip_Q ();
fail "Q.of_string" Q.of_string "0b2";
fail "Q.of_string" Q.of_string "0o8";
fail "Q.of_string" Q.of_string "0xg";
fail "Q.of_string" Q.of_string "0xG";
fail "Q.of_string" Q.of_string "0A";
succ "Q.of_string" Q.of_string "" Q.zero;
succ "Q.of_string" Q.of_string "+" Q.zero;
succ "Q.of_string" Q.of_string "-" Q.zero;
succ "Q.of_string" Q.of_string "0x" Q.zero;
succ "Q.of_string" Q.of_string "0X" Q.zero;
succ "Q.of_string" Q.of_string "0o" Q.zero;
succ "Q.of_string" Q.of_string "0O" Q.zero;
succ "Q.of_string" Q.of_string "0b" Q.zero;
succ "Q.of_string" Q.of_string "0B" Q.zero;
succ "Q.of_string" Q.of_string "0b101" (Q.of_string "5");
succ "Q.of_string" Q.of_string "0B101" (Q.of_string "5");
succ "Q.of_string" Q.of_string "0o101" (Q.of_string "65");
succ "Q.of_string" Q.of_string "0O101" (Q.of_string "65");
fail "Q.of_string" Q.of_string "0b2";
fail "Q.of_string" Q.of_string "0o8";
fail "Q.of_string" Q.of_string "0xg";
fail "Q.of_string" Q.of_string "0xG";
fail "Q.of_string" Q.of_string "0A";
fail "Q.of_string" Q.of_string "-0b0.1e1";
fail "Q.of_string" Q.of_string "-0o0.1E1";
fail "Q.of_string" Q.of_string "-0b0.1P1";
fail "Q.of_string" Q.of_string "-0o0.1p1";
fail "Q.of_string" Q.of_string "-0.1P1";
fail "Q.of_string" Q.of_string "-0.1p1";
succ "Q.of_string" Q.of_string "0x1e2" (Q.of_int 482);
succ "Q.of_string" Q.of_string "1e2" (Q.of_int 100);
succ "Q.of_string" Q.of_string "+" Q.zero;
succ "Q.of_string" Q.of_string "-+" Q.zero;
succ "Q.of_string" Q.of_string "-1" Q.minus_one;
succ "Q.of_string" Q.of_string "+0xFF.8" (Q.of_float 255.5);
succ "Q.of_string" Q.of_string "+0xff.8" (Q.of_float 255.5);
succ "Q.of_string" Q.of_string "-0xFF.8" (Q.of_float (-255.5));
succ "Q.of_string" Q.of_string "-0xff.8" (Q.of_float (-255.5));
succ "Q.of_string" Q.of_string "-0.1e1" (Q.of_float (float_of_string "-0.1e1")) ;
succ "Q.of_string" Q.of_string "-0.1E1" (Q.of_float (float_of_string "-0.1E1")) ;
succ "Q.of_string" Q.of_string "-0x0.1P1" (Q.of_float (float_of_string "-0x0.1P1")) ;
succ "Q.of_string" Q.of_string "-0x0.1p1" (Q.of_float (float_of_string "-0x0.1p1")) ;
succ "Q.of_string" Q.of_string "6.674e-11" (Q.of_string "0.00000000006674") ;
q_and_float_agree "-0x0.1p1" ;
q_and_float_agree "-0x0.1P1" ;
q_and_float_agree "-0x0.1p10" ;
q_and_float_agree "-0x0.1p10" ;
q_and_float_agree "1_2.34e03";
q_and_float_agree "12_.34e03";
q_and_float_agree "12._34e03";
q_and_float_agree "12.3_4e03";
q_and_float_agree "12.34_e03";
(* float_of_string accept leading underscores after ( 'e' | 'E'), Q does not. *)
(* q_and_float_agree "12.34e_03"; *)
q_and_float_agree "12.34e0_3";
q_and_float_agree "12.34e03_";
q_and_float_agree "000_001";
q_and_float_agree "001_000";
q_and_float_agree "123.";
(* underscores right after dot are accepted. *)
q_and_float_agree "1._001";
q_and_float_agree "._001";
(* float_of_string doesn't accept strings without digits, Q and Z do (e.g. "+", "-", "0x", "." *)
(* q_and_float_agree "."; *)
(* q_and_float_agree "._"; *)
q_and_float_agree "0.x00a";
q_and_float_agree ".-001";
()
let _ = test_of_string_Q ()

View file

@ -0,0 +1,65 @@
(* Pi digits computed with the streaming algorithm given on pages 4, 6
& 7 of "Unbounded Spigot Algorithms for the Digits of Pi", Jeremy
Gibbons, August 2004. *)
open Printf
let zero = Z.zero
and one = Z.one
and three = Z.of_int 3
and four = Z.of_int 4
and ten = Z.of_int 10
and neg_ten = Z.of_int (-10)
;;
(* Linear Fractional (aka M=F6bius) Transformations *)
module LFT = struct
let floor_ev (q, r, s, t) x =
Z.((q * x + r) / (s * x + t))
let unit = (one, zero, zero, one)
let comp (q, r, s, t) (q', r', s', t') =
Z.(q * q' + r * s', q * r' + r * t',
s * q' + t * s', s * r' + t * t')
end
let next z = LFT.floor_ev z three
let safe z n = (n = LFT.floor_ev z four)
let prod z n = LFT.comp (ten, Z.(neg_ten * n), zero, one) z
let cons z k =
let den = 2 * k + 1 in
LFT.comp z (Z.of_int k, Z.of_int (2 * den), zero, Z.of_int den)
let rec digit k z n row col =
if n > 0 then
let y = next z in
if safe z y then
if col = 10 then (
let row = row + 10 in
printf "\t:%i\n%a" row Z.output y;
digit k (prod z y) (n - 1) row 1
)
else (
printf "%a" Z.output y;
digit k (prod z y) (n - 1) row (col + 1)
)
else digit (k + 1) (cons z k) n row col
else
printf "%*s\t:%i\n" (10 - col) "" (row + col)
let digits n = digit 1 LFT.unit n 0 0
let usage () =
prerr_endline "Usage: pi <number of digits to compute for pi>";
exit 2
let _ =
let args = Sys.argv in
if Array.length args <> 2 then usage () else
digits (int_of_string Sys.argv.(1))

View file

@ -0,0 +1,50 @@
3141592653 :10
5897932384 :20
6264338327 :30
9502884197 :40
1693993751 :50
0582097494 :60
4592307816 :70
4062862089 :80
9862803482 :90
5342117067 :100
9821480865 :110
1328230664 :120
7093844609 :130
5505822317 :140
2535940812 :150
8481117450 :160
2841027019 :170
3852110555 :180
9644622948 :190
9549303819 :200
6442881097 :210
5665933446 :220
1284756482 :230
3378678316 :240
5271201909 :250
1456485669 :260
2346034861 :270
0454326648 :280
2133936072 :290
6024914127 :300
3724587006 :310
6063155881 :320
7488152092 :330
0962829254 :340
0917153643 :350
6789259036 :360
0011330530 :370
5488204665 :380
2138414695 :390
1941511609 :400
4330572703 :410
6575959195 :420
3092186117 :430
3819326117 :440
9310511854 :450
8074462379 :460
9627495673 :470
5188575272 :480
4891227938 :490
1830119491 :500

View file

@ -0,0 +1,27 @@
/* Auxiliary function to control FP rounding mode. Assumes ISO C99. */
#include <fenv.h>
#include <caml/mlvalues.h>
#ifndef FE_DOWNWARD
#define FE_DOWNWARD (-1)
#endif
#ifndef FE_TONEAREST
#define FE_TONEAREST (-1)
#endif
#ifndef FE_TOWARDZERO
#define FE_TOWARDZERO (-1)
#endif
#ifndef FE_UPWARD
#define FE_UPWARD (-1)
#endif
static int modes[4] = {
FE_DOWNWARD, FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD
};
CAMLprim value caml_ztest_setround(value vmode)
{
int rc = fesetround(modes[Int_val(vmode)]);
return Val_bool(rc == 0);
}

View file

@ -0,0 +1,154 @@
open Printf
(* Timing harness harness *)
let time fn arg =
let start = Sys.time() in
let rec time accu =
let qty = fn arg in
let duration = Sys.time() -. start in
let qty = float qty in
if duration >= 1.0
then duration /. (accu +. qty)
else time (accu +. qty)
in time 0.0
let time_repeat rep fn arg =
time (fun () -> for i = 1 to rep do ignore (fn arg) done; rep) ()
(* Basic arithmetic operations *)
let add (x, y) =
for i = 1 to 50_000_000 do
ignore (Sys.opaque_identity (Z.add x y))
done;
50_000_000
let sub (x, y) =
for i = 1 to 50_000_000 do
ignore (Sys.opaque_identity (Z.sub x y))
done;
50_000_000
let mul (x, y) =
for i = 1 to 50_000_000 do
ignore (Sys.opaque_identity (Z.mul x y))
done;
50_000_000
let div (x, y) =
for i = 1 to 10_000_000 do
ignore (Sys.opaque_identity (Z.div x y))
done;
1_000_000
let shl (x, y) =
for i = 1 to 50_000_000 do
ignore (Sys.opaque_identity (Z.shift_left x y))
done;
50_000_000
let big = Z.pow (Z.of_int 17) 150
let med = Z.pow (Z.of_int 3) 150
let _ =
printf "%.2e add (small, no overflow)\n%!"
(time add (Z.of_int 1, Z.of_int 2));
printf "%.2e add (small, overflow)\n%!"
(time add (Z.of_int max_int, Z.of_int 2));
printf "%.2e add (small, big)\n%!"
(time add (Z.of_int 1, big));
printf "%.2e add (big, big)\n%!"
(time add (big, big));
printf "%.2e sub (small, no overflow)\n%!"
(time sub (Z.of_int 1, Z.of_int 2));
printf "%.2e sub (small, overflow)\n%!"
(time sub (Z.of_int max_int, Z.of_int (-2)));
printf "%.2e sub (big, small)\n%!"
(time sub (big, Z.of_int 1));
printf "%.2e sub (big, big)\n%!"
(time sub (big, big));
printf "%.2e mul (small, no overflow)\n%!"
(time mul (Z.of_int 42, Z.of_int 74));
printf "%.2e mul (small, overflow)\n%!"
(time mul (Z.of_int max_int, Z.of_int 3));
printf "%.2e mul (small, big)\n%!"
(time mul (Z.of_int 3, big));
printf "%.2e mul (medium, medium)\n%!"
(time mul (med, med));
printf "%.2e mul (big, big)\n%!"
(time mul (big, big));
printf "%.2e div (small, small)\n%!"
(time div (Z.of_int 12345678, Z.of_int 443));
printf "%.2e div (big, small)\n%!"
(time div (big, Z.of_int 443));
printf "%.2e div (big, medium)\n%!"
(time div (big, med));
printf "%.2e shl (small, no overflow)\n%!"
(time shl (Z.of_int 3, 10));
printf "%.2e shl (small, overflow)\n%!"
(time shl (Z.of_int max_int, 2));
printf "%.2e shl (big)\n%!"
(time shl (big, 42))
(* Factorial *)
let rec fact_z n =
if n <= 0 then Z.one else Z.mul (Z.of_int n) (fact_z (n-1))
let _ =
printf "%.2e fact 10\n%!"
(time_repeat 1_000_000 fact_z 10);
printf "%.2e fact 40\n%!"
(time_repeat 10_000 fact_z 40);
printf "%.2e fact 200\n%!"
(time_repeat 10_000 fact_z 200)
(* Fibonacci *)
let rec fib_int n =
if n < 2 then 1 else fib_int(n-1) + fib_int(n-2)
let rec fib_natint n =
if n < 2 then 1n else Nativeint.add (fib_natint(n-1)) (fib_natint(n-2))
let rec fib_z n =
if n < 2 then Z.one else Z.add (fib_z(n-1)) (fib_z(n-2))
let fib_arg = 32
let _ =
printf "%.2e fib (int)\n%!"
(time_repeat 100 fib_int fib_arg);
printf "%.2e fib (nativeint)\n%!"
(time_repeat 100 fib_natint fib_arg);
printf "%.2e fib (Z)\n%!"
(time_repeat 100 fib_z fib_arg)
(* Takeushi *)
let rec tak_int (x, y, z) =
if x > y
then tak_int(tak_int (x-1, y, z), tak_int (y-1, z, x), tak_int (z-1, x, y))
else z
let rec tak_natint (x, y, z) =
if x > y
then tak_natint(tak_natint (Nativeint.sub x 1n, y, z),
tak_natint (Nativeint.sub y 1n, z, x),
tak_natint (Nativeint.sub z 1n, x, y))
else z
let rec tak_z (x, y, z) =
if Z.compare x y > 0
then tak_z(tak_z (Z.pred x, y, z),
tak_z (Z.pred y, z, x),
tak_z (Z.pred z, x, y))
else z
let _ =
printf "%.2e tak (int)\n%!"
(time_repeat 1000 tak_int (18,12,6));
printf "%.2e tak (nativeint)\n%!"
(time_repeat 1000 tak_natint (18n,12n,6n));
printf "%.2e tak (Z)\n%!"
(time_repeat 1000 tak_z (Z.of_int 18, Z.of_int 12, Z.of_int 6))

View file

@ -0,0 +1,134 @@
(* Testing Z.to_float *)
open Printf
type rounding_mode =
FE_DOWNWARD | FE_TONEAREST | FE_TOWARDZERO | FE_UPWARD
external setround: rounding_mode -> bool = "caml_ztest_setround"
external format_float: string -> float -> string = "caml_format_float"
let hex_of_float f = format_float "%a" f
(* For testing, we use randomly-generated integers of the form
<signed 64-bit integer> * 2^<exponent>
We can predict their FP value by converting the integer part to FP,
then scale by the exponent using ldexp. *)
let test1 (mant: int64) (exp: int) =
let expected = ldexp (Int64.to_float mant) exp in
let actual = Z.to_float (Z.shift_left (Z.of_int64 mant) exp) in
if actual = expected then true else begin
printf "%Ld * 2^%d: expected %s, got %s\n"
mant exp (hex_of_float expected) (hex_of_float actual);
false
end
let rnd64 () =
let m1 = Random.bits() in (* 30 bits *)
let m2 = Random.bits() in (* 30 bits *)
let m3 = Random.bits() in
Int64.(logor (of_int m1)
(logor (shift_left (of_int m2) 30)
(shift_left (of_int m3) 60)))
let testN numrounds =
printf " (%d tests)... %!" numrounds;
let errors = ref 0 in
(* Some random int64 values *)
for i = 1 to numrounds do
let m = Random.int64 Int64.max_int in
if not (test1 m 0) then incr errors;
if not (test1 (Int64.neg m) 0) then incr errors
done;
(* Some random int64 values scaled by some random power of 2 *)
for i = 1 to numrounds do
let m = rnd64() in
let exp = Random.int 1100 in (* sometimes +inf will result *)
if not (test1 m exp) then incr errors
done;
(* Special test close to a rounding point *)
for i = 0 to 15 do
let m = Int64.(add 0xfffffffffffff0L (of_int i)) in
if not (test1 m 32) then incr errors;
if not (test1 (Int64.neg m) 32) then incr errors
done;
if !errors = 0
then printf "passed\n%!"
else printf "FAILED (%d errors)\n%!" !errors
let testQ1 (mant1: int64) (exp1: int) (mant2: int64) (exp2: int) =
let expected =
ldexp (Int64.to_float mant1) exp1 /. ldexp (Int64.to_float mant2) exp2 in
let actual =
Q.to_float (Q.make (Z.shift_left (Z.of_int64 mant1) exp1)
(Z.shift_left (Z.of_int64 mant2) exp2)) in
if compare actual expected = 0 then true else begin
printf "%Ld * 2^%d / %Ld * 2^%d : expected %s, got %s\n"
mant1 exp1 mant2 exp2 (hex_of_float expected) (hex_of_float actual);
false
end
let testQN numrounds =
printf " (%d tests)... %!" numrounds;
let errors = ref 0 in
(* Some special values *)
if not (testQ1 0L 0 1L 0) then incr errors;
if not (testQ1 1L 0 0L 0) then incr errors;
if not (testQ1 (-1L) 0 0L 0) then incr errors;
if not (testQ1 0L 0 0L 0) then incr errors;
(* Some random fractions *)
for i = 1 to numrounds do
let m1 = Random.int64 0x20000000000000L in
let m1 = if Random.bool() then m1 else Int64.neg m1 in
let exp1 = Random.int 500 in
let m2 = Random.int64 0x20000000000000L in
let exp2 = Random.int 500 in
if not (testQ1 m1 exp1 m2 exp2) then incr errors
done;
if !errors = 0
then printf "passed\n%!"
else printf "FAILED (%d errors)\n%!" !errors
let _ =
let numrounds =
if Array.length Sys.argv >= 2
then int_of_string Sys.argv.(1)
else 100_000 in
printf "Default rounding mode (Z)";
testN numrounds;
printf "Default rounding mode (Q)";
testQN numrounds;
if setround FE_TOWARDZERO then begin
printf "Round toward zero (Z)";
testN numrounds;
printf "Round toward zero (Q)";
testQN numrounds
end else begin
printf "Round toward zero not supported, skipping\n"
end;
if setround FE_DOWNWARD then begin
printf "Round downward (Z)";
testN numrounds;
printf "Round downward (Q)";
testQN numrounds
end else begin
printf "Round downward not supported, skipping\n"
end;
if setround FE_UPWARD then begin
printf "Round upward (Z)";
testN numrounds;
printf "Round upward (Q)";
testQN numrounds
end else begin
printf "Round upward not supported, skipping\n"
end;
if setround FE_TONEAREST then begin
printf "Round to nearest (Z)";
testN numrounds;
printf "Round to nearest (Q)";
testQN numrounds
end else begin
printf "Round to nearest not supported, skipping\n"
end

View file

@ -0,0 +1,35 @@
module I = Z
let pr ch x =
output_string ch (I.to_string x);
flush ch
let chk_extract x o l =
let expected =
I.logand (I.shift_right x o) (I.pred (I.shift_left (I.of_int 1) l))
and actual =
I.extract x o l in
if actual <> expected then (Printf.printf "extract %a %d %d = %a found %a\n" pr x o l pr expected pr actual; failwith "test failed")
let doit () =
let max = 128 in
for l = 1 to max do
if l mod 16 == 0 then Printf.printf "%i/%i\n%!" l max;
for o = 0 to 256 do
for n = 0 to 256 do
let x = I.shift_left I.one n in
chk_extract x o l;
chk_extract (I.mul x x) o l;
chk_extract (I.mul x (I.mul x x)) o l;
chk_extract (I.succ x) o l;
chk_extract (I.pred x) o l;
chk_extract (I.neg (I.mul x x)) o l;
chk_extract (I.neg (I.mul x (I.mul x x))) o l;
chk_extract (I.neg x) o l;
chk_extract (I.neg (I.succ x)) o l;
chk_extract (I.neg (I.pred x)) o l;
done
done
done
let _ = doit ()

View file

@ -0,0 +1,920 @@
(* Simple tests for the Z and Q modules.
This file is part of the Zarith library
http://forge.ocamlcore.org/projects/zarith .
It is distributed under LGPL 2 licensing, with static linking exception.
See the LICENSE file included in the distribution.
Copyright (c) 2010-2011 Antoine Miné, Abstraction project.
Abstraction is part of the LIENS (Laboratoire d'Informatique de l'ENS),
a joint laboratory by:
CNRS (Centre national de la recherche scientifique, France),
ENS (École normale supérieure, Paris, France),
INRIA Rocquencourt (Institut national de recherche en informatique, France).
*)
(* testing Z *)
module I = Z
let pr ch x =
output_string ch (I.to_string x);
flush ch
let pr2 ch (x,y) =
Printf.fprintf ch "%s, %s" (I.to_string x) (I.to_string y);
flush ch
let pr3 ch (x,y,z) =
Printf.fprintf ch "%s, %s, %s"
(I.to_string x) (I.to_string y) (I.to_string z);
flush ch
let prfloat ch (x,y : float * float) =
if x = y then
Printf.fprintf ch "OK"
else
Printf.fprintf ch "WRONG! (expected %g, got %g)" y x
let prmarshal ch (x,y : I.t * I.t) =
(if I.equal x y then
Printf.fprintf ch "OK"
else
Printf.fprintf ch "WRONG! (expected %a, got %a)" pr y pr x);
flush ch
let pow2 n =
let rec doit acc n =
if n<=0 then acc else doit (I.add acc acc) (n-1)
in
doit I.one n
let fact n =
let rec doit acc n =
if n<=1 then acc
else doit (I.mul acc (I.of_int n)) (n-1)
in
doit I.one n
let pow a b =
let rec doit b =
if b <= 0 then I.one else
let acc = doit (b lsr 1) in
if b land 1 = 1 then I.mul (I.mul acc acc) (I.of_int a)
else I.mul acc acc
in
doit b
let cvt_int x =
(string_of_bool (I.fits_int x))
^","^
(try string_of_int (I.to_int x) with I.Overflow -> "ovf")
let cvt_int32 x =
(string_of_bool (I.fits_int32 x))
^","^
(try Int32.to_string (I.to_int32 x) with I.Overflow -> "ovf")
let cvt_int64 x =
(string_of_bool (I.fits_int64 x))
^","^
(try Int64.to_string (I.to_int64 x) with I.Overflow -> "ovf")
let cvt_nativeint x =
(string_of_bool (I.fits_nativeint x))
^","^
(try Nativeint.to_string (I.to_nativeint x) with I.Overflow -> "ovf")
let cvt_int32_unsigned x =
(string_of_bool (I.fits_int32_unsigned x))
^","^
(try Int32.to_string (I.to_int32_unsigned x) with I.Overflow -> "ovf")
let cvt_int64_unsigned x =
(string_of_bool (I.fits_int64_unsigned x))
^","^
(try Int64.to_string (I.to_int64_unsigned x) with I.Overflow -> "ovf")
let cvt_nativeint_unsigned x =
(string_of_bool (I.fits_nativeint_unsigned x))
^","^
(try Nativeint.to_string (I.to_nativeint_unsigned x) with I.Overflow -> "ovf")
let p2 = I.of_int 2
let p3 = I.of_int 3
let p30 = pow2 30
let p62 = pow2 62
let p300 = pow2 300
let p120 = pow2 120
let p121 = pow2 121
let maxi = I.of_int max_int
let mini = I.of_int min_int
let maxi32 = I.of_int32 Int32.max_int
let mini32 = I.of_int32 Int32.min_int
let maxi64 = I.of_int64 Int64.max_int
let mini64 = I.of_int64 Int64.min_int
let maxni = I.of_nativeint Nativeint.max_int
let minni = I.of_nativeint Nativeint.min_int
let chk_bits x =
Printf.printf "to_bits %a\n =" pr x;
String.iter (fun c -> Printf.printf " %02x" (Char.code c)) (I.to_bits x);
Printf.printf "\n";
assert(I.equal (I.abs x) (I.of_bits (I.to_bits x)));
assert((I.to_bits x) = (I.to_bits (I.neg x)));
Printf.printf "marshal round trip %a\n =" pr x;
let y = Marshal.(from_string (to_string x []) 0) in
Printf.printf " %a\n" prmarshal (y, x)
let chk_extract (x, o, l) =
let expected =
I.logand (I.shift_right x o) (I.pred (I.shift_left (I.of_int 1) l))
and actual =
I.extract x o l in
Printf.printf "extract %a %d %d = %a " pr x o l pr actual;
if I.equal actual expected
then Printf.printf "(passed)\n"
else Printf.printf "(FAILED, expected %a)\n" pr expected
let chk_signed_extract (x, o, l) =
let uns_res = I.extract x o l in
let expected =
if I.compare uns_res (I.shift_left (I.of_int 1) (l-1)) >= 0
then I.sub uns_res (I.shift_left (I.of_int 1) l)
else uns_res in
let actual =
I.signed_extract x o l in
Printf.printf "signed_extract %a %d %d = %a " pr x o l pr actual;
if I.equal actual expected
then Printf.printf "(passed)\n"
else Printf.printf "(FAILED, expected %a)\n" pr expected
let chk_numbits_tz x =
Printf.printf "numbits / trailing_zeros %a " pr x;
let n = I.numbits x and z = I.trailing_zeros x in
if
if I.equal x I.zero then
n = 0 && z = max_int
else
n > 0 && z >= 0 && z < n
&& I.leq (I.shift_left I.one (n-1)) (I.abs x)
&& I.lt (I.abs x) (I.shift_left I.one n)
&& (z = 0 || I.equal (I.extract x 0 z) I.zero)
&& I.testbit x z
then Printf.printf "(passed)\n"
else Printf.printf "(FAILED)\n"
let chk_testbit x =
Printf.printf "testbit %a " pr x;
let n = I.numbits x in
let ok = ref true in
for i = 0 to n + 64 do
let actual = I.testbit x i
and expected = I.extract x i 1 in
if not (I.equal expected (if actual then I.one else I.zero))
then begin Printf.printf "(error on %d) " i; ok := false end
done;
if !ok
then Printf.printf "(passed)\n"
else Printf.printf "(FAILED)\n"
let pr_byte =
let state = ref 0 in
fun () ->
state := (!state * 65793 + 4282663) land 0xFF_FF_FF;
!state lsr 16
let pr_bytes buf pos len =
for i = pos to pos + len - 1 do
Bytes.set_uint8 buf i (pr_byte ())
done
let test_Z() =
Printf.printf "0\n = %a\n" pr I.zero;
Printf.printf "1\n = %a\n" pr I.one;
Printf.printf "-1\n = %a\n" pr I.minus_one;
Printf.printf "42\n = %a\n" pr (I.of_int 42);
Printf.printf "1+1\n = %a\n" pr (I.add I.one I.one);
Printf.printf "1-1\n = %a\n" pr (I.sub I.one I.one);
Printf.printf "- 1\n = %a\n" pr (I.neg I.one);
Printf.printf "0-1\n = %a\n" pr (I.sub I.zero I.one);
Printf.printf "max_int\n = %a\n" pr maxi;
Printf.printf "min_int\n = %a\n" pr mini;
Printf.printf "-max_int\n = %a\n" pr (I.neg maxi);
Printf.printf "-min_int\n = %a\n" pr (I.neg mini);
Printf.printf "2^300\n = %a\n" pr p300;
Printf.printf "2^120\n = %a\n" pr p120;
Printf.printf "2^300+2^120\n = %a\n" pr (I.add p300 p120);
Printf.printf "2^300-2^120\n = %a\n" pr (I.sub p300 p120);
Printf.printf "2^300+(-(2^120))\n = %a\n" pr (I.add p300 (I.neg p120));
Printf.printf "2^120-2^300\n = %a\n" pr (I.sub p120 p300);
Printf.printf "2^120+(-(2^300))\n = %a\n" pr (I.add p120 (I.neg p300));
Printf.printf "-(2^120)+(-(2^300))\n = %a\n" pr (I.add (I.neg p120) (I.neg p300));
Printf.printf "-(2^120)-2^300\n = %a\n" pr (I.sub (I.neg p120) p300);
Printf.printf "2^300-2^300\n = %a\n" pr (I.sub p300 p300);
Printf.printf "2^121\n = %a\n" pr p121;
Printf.printf "2^121+2^120\n = %a\n" pr (I.add p121 p120);
Printf.printf "2^121-2^120\n = %a\n" pr (I.sub p121 p120);
Printf.printf "2^121+(-(2^120))\n = %a\n" pr (I.add p121 (I.neg p120));
Printf.printf "2^120-2^121\n = %a\n" pr (I.sub p120 p121);
Printf.printf "2^120+(-(2^121))\n = %a\n" pr (I.add p120 (I.neg p121));
Printf.printf "-(2^120)+(-(2^121))\n = %a\n" pr (I.add (I.neg p120) (I.neg p121));
Printf.printf "-(2^120)-2^121\n = %a\n" pr (I.sub (I.neg p120) p121);
Printf.printf "2^121+0\n = %a\n" pr (I.add p121 I.zero);
Printf.printf "2^121-0\n = %a\n" pr (I.sub p121 I.zero);
Printf.printf "0+2^121\n = %a\n" pr (I.add I.zero p121);
Printf.printf "0-2^121\n = %a\n" pr (I.sub I.zero p121);
Printf.printf "2^300+1\n = %a\n" pr (I.add p300 I.one);
Printf.printf "2^300-1\n = %a\n" pr (I.sub p300 I.one);
Printf.printf "1+2^300\n = %a\n" pr (I.add I.one p300);
Printf.printf "1-2^300\n = %a\n" pr (I.sub I.one p300);
Printf.printf "2^300+(-1)\n = %a\n" pr (I.add p300 I.minus_one);
Printf.printf "2^300-(-1)\n = %a\n" pr (I.sub p300 I.minus_one);
Printf.printf "(-1)+2^300\n = %a\n" pr (I.add I.minus_one p300);
Printf.printf "(-1)-2^300\n = %a\n" pr (I.sub I.minus_one p300);
Printf.printf "-(2^300)+1\n = %a\n" pr (I.add (I.neg p300) I.one);
Printf.printf "-(2^300)-1\n = %a\n" pr (I.sub (I.neg p300) I.one);
Printf.printf "1+(-(2^300))\n = %a\n" pr (I.add I.one (I.neg p300));
Printf.printf "1-(-(2^300))\n = %a\n" pr (I.sub I.one (I.neg p300));
Printf.printf "-(2^300)+(-1)\n = %a\n" pr (I.add (I.neg p300) I.minus_one);
Printf.printf "-(2^300)-(-1)\n = %a\n" pr (I.sub (I.neg p300) I.minus_one);
Printf.printf "(-1)+(-(2^300))\n = %a\n" pr (I.add I.minus_one (I.neg p300));
Printf.printf "(-1)-(-(2^300))\n = %a\n" pr (I.sub I.minus_one (I.neg p300));
Printf.printf "max_int+1\n = %a\n" pr (I.add maxi I.one);
Printf.printf "min_int-1\n = %a\n" pr (I.sub mini I.one);
Printf.printf "-max_int-1\n = %a\n" pr (I.sub (I.neg maxi) I.one);
Printf.printf "-min_int-1\n = %a\n" pr (I.sub (I.neg mini) I.one);
Printf.printf "5! = %a\n" pr (fact 5);
Printf.printf "12! = %a\n" pr (fact 12);
Printf.printf "15! = %a\n" pr (fact 15);
Printf.printf "20! = %a\n" pr (fact 20);
Printf.printf "25! = %a\n" pr (fact 25);
Printf.printf "50! = %a\n" pr (fact 50);
Printf.printf "2^300*2^120\n = %a\n" pr (I.mul p300 p120);
Printf.printf "2^120*2^300\n = %a\n" pr (I.mul p120 p300);
Printf.printf "2^300*(-(2^120))\n = %a\n" pr (I.mul p300 (I.neg p120));
Printf.printf "2^120*(-(2^300))\n = %a\n" pr (I.mul p120 (I.neg p300));
Printf.printf "-(2^120)*(-(2^300))\n = %a\n" pr (I.mul (I.neg p120) (I.neg p300));
Printf.printf "2^121*2^120\n = %a\n" pr (I.mul p121 p120);
Printf.printf "2^120*2^121\n = %a\n" pr (I.mul p120 p121);
Printf.printf "2^121*0\n = %a\n" pr (I.mul p121 I.zero);
Printf.printf "0*2^121\n = %a\n" pr (I.mul I.zero p121);
Printf.printf "2^300*1\n = %a\n" pr (I.mul p300 I.one);
Printf.printf "1*2^300\n = %a\n" pr (I.mul I.one p300);
Printf.printf "2^300*(-1)\n = %a\n" pr (I.mul p300 I.minus_one);
Printf.printf "(-1)*2^300\n = %a\n" pr (I.mul I.minus_one p300);
Printf.printf "-(2^300)*1\n = %a\n" pr (I.mul (I.neg p300) I.one);
Printf.printf "1*(-(2^300))\n = %a\n" pr (I.mul I.one (I.neg p300));
Printf.printf "-(2^300)*(-1)\n = %a\n" pr (I.mul (I.neg p300) I.minus_one);
Printf.printf "(-1)*(-(2^300))\n = %a\n" pr (I.mul I.minus_one (I.neg p300));
Printf.printf "1*(2^30)\n = %a\n" pr (I.mul I.one p30);
Printf.printf "1*(2^62)\n = %a\n" pr (I.mul I.one p62);
Printf.printf "(2^30)*(2^30)\n = %a\n" pr (I.mul p30 p30);
Printf.printf "(2^62)*(2^62)\n = %a\n" pr (I.mul p62 p62);
Printf.printf "0+1\n = %a\n" pr (I.succ I.zero);
Printf.printf "1+1\n = %a\n" pr (I.succ I.one);
Printf.printf "-1+1\n = %a\n" pr (I.succ I.minus_one);
Printf.printf "2+1\n = %a\n" pr (I.succ p2);
Printf.printf "-2+1\n = %a\n" pr (I.succ (I.neg p2));
Printf.printf "(2^300)+1\n = %a\n" pr (I.succ p300);
Printf.printf "-(2^300)+1\n = %a\n" pr (I.succ (I.neg p300));
Printf.printf "0-1\n = %a\n" pr (I.pred I.zero);
Printf.printf "1-1\n = %a\n" pr (I.pred I.one);
Printf.printf "-1-1\n = %a\n" pr (I.pred I.minus_one);
Printf.printf "2-1\n = %a\n" pr (I.pred p2);
Printf.printf "-2-1\n = %a\n" pr (I.pred (I.neg p2));
Printf.printf "(2^300)-1\n = %a\n" pr (I.pred p300);
Printf.printf "-(2^300)-1\n = %a\n" pr (I.pred (I.neg p300));
Printf.printf "max_int+1\n = %a\n" pr (I.succ maxi);
Printf.printf "min_int-1\n = %a\n" pr (I.pred mini);
Printf.printf "-max_int-1\n = %a\n" pr (I.pred (I.neg maxi));
Printf.printf "-min_int-1\n = %a\n" pr (I.pred (I.neg mini));
Printf.printf "abs(0)\n = %a\n" pr (I.abs I.zero);
Printf.printf "abs(1)\n = %a\n" pr (I.abs I.one);
Printf.printf "abs(-1)\n = %a\n" pr (I.abs I.minus_one);
Printf.printf "abs(min_int)\n = %a\n" pr (I.abs mini);
Printf.printf "abs(2^300)\n = %a\n" pr (I.abs p300);
Printf.printf "abs(-(2^300))\n = %a\n" pr (I.abs (I.neg p300));
Printf.printf "max_nativeint\n = %a\n" pr maxni;
Printf.printf "max_int32\n = %a\n" pr maxi32;
Printf.printf "max_int64\n = %a\n" pr maxi64;
Printf.printf "to_int 1\n = %s\n" (cvt_int I.one);
Printf.printf "to_int max_int\n = %s\n" (cvt_int maxi);
Printf.printf "to_int max_nativeint\n = %s\n" (cvt_int maxni);
Printf.printf "to_int max_int32\n = %s\n" (cvt_int maxi32);
Printf.printf "to_int max_int64\n = %s\n" (cvt_int maxi64);
Printf.printf "to_int32 1\n = %s\n" (cvt_int32 I.one);
Printf.printf "to_int32 max_int\n = %s\n" (cvt_int32 maxi);
Printf.printf "to_int32 max_nativeint\n = %s\n" (cvt_int32 maxni);
Printf.printf "to_int32 max_int32\n = %s\n" (cvt_int32 maxi32);
Printf.printf "to_int32 max_int64\n = %s\n" (cvt_int32 maxi64);
Printf.printf "to_int64 1\n = %s\n" (cvt_int64 I.one);
Printf.printf "to_int64 max_int\n = %s\n" (cvt_int64 maxi);
Printf.printf "to_int64 max_nativeint\n = %s\n" (cvt_int64 maxni);
Printf.printf "to_int64 max_int32\n = %s\n" (cvt_int64 maxi32);
Printf.printf "to_int64 max_int64\n = %s\n" (cvt_int64 maxi64);
Printf.printf "to_nativeint 1\n = %s\n" (cvt_nativeint I.one);
Printf.printf "to_nativeint max_int\n = %s\n" (cvt_nativeint maxi);
Printf.printf "to_nativeint max_nativeint\n = %s\n" (cvt_nativeint maxni);
Printf.printf "to_nativeint max_int32\n = %s\n" (cvt_nativeint maxi32);
Printf.printf "to_nativeint max_int64\n = %s\n" (cvt_nativeint maxi64);
Printf.printf "to_int -min_int\n = %s\n" (cvt_int (I.neg mini));
Printf.printf "to_int -min_nativeint\n = %s\n" (cvt_int (I.neg minni));
Printf.printf "to_int -min_int32\n = %s\n" (cvt_int (I.neg mini32));
Printf.printf "to_int -min_int64\n = %s\n" (cvt_int (I.neg mini64));
Printf.printf "to_int32 -min_int\n = %s\n" (cvt_int32 (I.neg mini));
Printf.printf "to_int32 -min_nativeint\n = %s\n" (cvt_int32 (I.neg minni));
Printf.printf "to_int32 -min_int32\n = %s\n" (cvt_int32 (I.neg mini32));
Printf.printf "to_int32 -min_int64\n = %s\n" (cvt_int32(I.neg mini64));
Printf.printf "to_int64 -min_int\n = %s\n" (cvt_int64 (I.neg mini));
Printf.printf "to_int64 -min_nativeint\n = %s\n" (cvt_int64 (I.neg minni));
Printf.printf "to_int64 -min_int32\n = %s\n" (cvt_int64 (I.neg mini32));
Printf.printf "to_int64 -min_int64\n = %s\n" (cvt_int64 (I.neg mini64));
Printf.printf "to_nativeint -min_int\n = %s\n" (cvt_nativeint (I.neg mini));
Printf.printf "to_nativeint -min_nativeint\n = %s\n" (cvt_nativeint (I.neg minni));
Printf.printf "to_nativeint -min_int32\n = %s\n" (cvt_nativeint (I.neg mini32));
Printf.printf "to_nativeint -min_int64\n = %s\n" (cvt_nativeint (I.neg mini64));
Printf.printf "to_int32_unsigned 1\n = %s\n" (cvt_int32_unsigned I.one);
Printf.printf "to_int32_unsigned -1\n = %s\n" (cvt_int32_unsigned I.minus_one);
Printf.printf "to_int32_unsigned max_int\n = %s\n" (cvt_int32_unsigned maxi);
Printf.printf "to_int32_unsigned max_nativeint\n = %s\n" (cvt_int32_unsigned maxni);
Printf.printf "to_int32_unsigned max_int32\n = %s\n" (cvt_int32_unsigned maxi32);
Printf.printf "to_int32_unsigned 2max_int32\n = %s\n" (cvt_int32_unsigned (I.mul p2 maxi32));
Printf.printf "to_int32_unsigned 3max_int32\n = %s\n" (cvt_int32_unsigned (I.mul p3 maxi32));
Printf.printf "to_int32_unsigned max_int64\n = %s\n" (cvt_int32_unsigned maxi64);
Printf.printf "to_int64_unsigned 1\n = %s\n" (cvt_int64_unsigned I.one);
Printf.printf "to_int64_unsigned -1\n = %s\n" (cvt_int64_unsigned I.minus_one);
Printf.printf "to_int64_unsigned max_int\n = %s\n" (cvt_int64_unsigned maxi);
Printf.printf "to_int64_unsigned max_nativeint\n = %s\n" (cvt_int64_unsigned maxni);
Printf.printf "to_int64_unsigned max_int32\n = %s\n" (cvt_int64_unsigned maxi32);
Printf.printf "to_int64_unsigned max_int64\n = %s\n" (cvt_int64_unsigned maxi64);
Printf.printf "to_int64_unsigned 2max_int64\n = %s\n" (cvt_int64_unsigned (I.mul p2 maxi64));
Printf.printf "to_int64_unsigned 3max_int64\n = %s\n" (cvt_int64_unsigned (I.mul p3 maxi64));
Printf.printf "to_nativeint_unsigned 1\n = %s\n" (cvt_nativeint_unsigned I.one);
Printf.printf "to_nativeint_unsigned -1\n = %s\n" (cvt_nativeint_unsigned I.minus_one);
Printf.printf "to_nativeint_unsigned max_int\n = %s\n" (cvt_nativeint_unsigned maxi);
Printf.printf "to_nativeint_unsigned max_nativeint\n = %s\n" (cvt_nativeint_unsigned maxni);
Printf.printf "to_nativeint_unsigned 2max_nativeint\n = %s\n" (cvt_nativeint_unsigned (I.mul p2 maxni));
Printf.printf "to_nativeint_unsigned max_int32\n = %s\n" (cvt_nativeint_unsigned maxi32);
Printf.printf "to_nativeint_unsigned max_int64\n = %s\n" (cvt_nativeint_unsigned maxi64);
Printf.printf "to_nativeint_unsigned 2max_int64\n = %s\n" (cvt_nativeint_unsigned (I.mul p2 maxi64));
Printf.printf "to_nativeint_unsigned 3max_int64\n = %s\n" (cvt_nativeint_unsigned (I.mul p3 maxi64));
Printf.printf "of_int32_unsigned -1\n = %a\n" pr (I.of_int32_unsigned (-1l));
Printf.printf "of_int64_unsigned -1\n = %a\n" pr (I.of_int64_unsigned (-1L));
Printf.printf "of_nativeint_unsigned -1\n = %a\n" pr (I.of_nativeint_unsigned (-1n));
Printf.printf "of_float 1.\n = %a\n" pr (I.of_float 1.);
Printf.printf "of_float -1.\n = %a\n" pr (I.of_float (-. 1.));
Printf.printf "of_float pi\n = %a\n" pr (I.of_float (2. *. acos 0.));
Printf.printf "of_float 2^30\n = %a\n" pr (I.of_float (ldexp 1. 30));
Printf.printf "of_float 2^31\n = %a\n" pr (I.of_float (ldexp 1. 31));
Printf.printf "of_float 2^32\n = %a\n" pr (I.of_float (ldexp 1. 32));
Printf.printf "of_float 2^33\n = %a\n" pr (I.of_float (ldexp 1. 33));
Printf.printf "of_float -2^30\n = %a\n" pr (I.of_float (-.(ldexp 1. 30)));
Printf.printf "of_float -2^31\n = %a\n" pr (I.of_float (-.(ldexp 1. 31)));
Printf.printf "of_float -2^32\n = %a\n" pr (I.of_float (-.(ldexp 1. 32)));
Printf.printf "of_float -2^33\n = %a\n" pr (I.of_float (-.(ldexp 1. 33)));
Printf.printf "of_float 2^61\n = %a\n" pr (I.of_float (ldexp 1. 61));
Printf.printf "of_float 2^62\n = %a\n" pr (I.of_float (ldexp 1. 62));
Printf.printf "of_float 2^63\n = %a\n" pr (I.of_float (ldexp 1. 63));
Printf.printf "of_float 2^64\n = %a\n" pr (I.of_float (ldexp 1. 64));
Printf.printf "of_float 2^65\n = %a\n" pr (I.of_float (ldexp 1. 65));
Printf.printf "of_float -2^61\n = %a\n" pr (I.of_float (-.(ldexp 1. 61)));
Printf.printf "of_float -2^62\n = %a\n" pr (I.of_float (-.(ldexp 1. 62)));
Printf.printf "of_float -2^63\n = %a\n" pr (I.of_float (-.(ldexp 1. 63)));
Printf.printf "of_float -2^64\n = %a\n" pr (I.of_float (-.(ldexp 1. 64)));
Printf.printf "of_float -2^65\n = %a\n" pr (I.of_float (-.(ldexp 1. 65)));
Printf.printf "of_float 2^120\n = %a\n" pr (I.of_float (ldexp 1. 120));
Printf.printf "of_float 2^300\n = %a\n" pr (I.of_float (ldexp 1. 300));
Printf.printf "of_float -2^120\n = %a\n" pr (I.of_float (-.(ldexp 1. 120)));
Printf.printf "of_float -2^300\n = %a\n" pr (I.of_float (-.(ldexp 1. 300)));
Printf.printf "of_float 0.5\n = %a\n" pr (I.of_float 0.5);
Printf.printf "of_float -0.5\n = %a\n" pr (I.of_float (-. 0.5));
Printf.printf "of_float 200.5\n = %a\n" pr (I.of_float 200.5);
Printf.printf "of_float -200.5\n = %a\n" pr (I.of_float (-. 200.5));
Printf.printf "to_float 0\n = %a\n" prfloat (I.to_float I.zero, 0.0);
Printf.printf "to_float 1\n = %a\n" prfloat (I.to_float I.one, 1.0);
Printf.printf "to_float -1\n = %a\n" prfloat (I.to_float I.minus_one, -1.0);
Printf.printf "to_float 2^120\n = %a\n" prfloat (I.to_float p120, ldexp 1.0 120);
Printf.printf "to_float -2^120\n = %a\n" prfloat (I.to_float (I.neg p120), -. (ldexp 1.0 120));
Printf.printf "to_float (2^120-1)\n = %a\n" prfloat (I.to_float (I.pred p120), ldexp 1.0 120);
Printf.printf "to_float (-2^120+1)\n = %a\n" prfloat (I.to_float (I.succ (I.neg p120)), -. (ldexp 1.0 120));
Printf.printf "to_float 2^63\n = %a\n" prfloat (I.to_float (pow2 63), ldexp 1.0 63);
Printf.printf "to_float -2^63\n = %a\n" prfloat (I.to_float (I.neg (pow2 63)), -. (ldexp 1.0 63));
Printf.printf "to_float (2^63-1)\n = %a\n" prfloat (I.to_float (I.pred (pow2 63)), ldexp 1.0 63);
Printf.printf "to_float (-2^63-1)\n = %a\n" prfloat (I.to_float (I.pred (I.neg (pow2 63))), -. (ldexp 1.0 63));
Printf.printf "to_float (-2^63+1)\n = %a\n" prfloat (I.to_float (I.succ (I.neg (pow2 63))), -. (ldexp 1.0 63));
Printf.printf "to_float 2^300\n = %a\n" prfloat (I.to_float p300, ldexp 1.0 300);
Printf.printf "to_float -2^300\n = %a\n" prfloat (I.to_float (I.neg p300), -. (ldexp 1.0 300));
Printf.printf "to_float (2^300-1)\n = %a\n" prfloat (I.to_float (I.pred p300), ldexp 1.0 300);
Printf.printf "to_float (-2^300+1)\n = %a\n" prfloat (I.to_float (I.succ (I.neg p300)), -. (ldexp 1.0 300));
Printf.printf "of_string 12\n = %a\n" pr (I.of_string "12");
Printf.printf "of_string 0x12\n = %a\n" pr (I.of_string "0x12");
Printf.printf "of_string 0b10\n = %a\n" pr (I.of_string "0b10");
Printf.printf "of_string 0o12\n = %a\n" pr (I.of_string "0o12");
Printf.printf "of_string -12\n = %a\n" pr (I.of_string "-12");
Printf.printf "of_string -0x12\n = %a\n" pr (I.of_string "-0x12");
Printf.printf "of_string -0b10\n = %a\n" pr (I.of_string "-0b10");
Printf.printf "of_string -0o12\n = %a\n" pr (I.of_string "-0o12");
Printf.printf "of_string 000123456789012345678901234567890\n = %a\n" pr (I.of_string "000123456789012345678901234567890");
Printf.printf "2^120 / 2^300 (trunc)\n = %a\n" pr (I.div p120 p300);
Printf.printf "max_int / 2 (trunc)\n = %a\n" pr (I.div maxi p2);
Printf.printf "(2^300+1) / 2^120 (trunc)\n = %a\n" pr (I.div (I.succ p300) p120);
Printf.printf "(-(2^300+1)) / 2^120 (trunc)\n = %a\n" pr (I.div (I.neg (I.succ p300)) p120);
Printf.printf "(2^300+1) / (-(2^120)) (trunc)\n = %a\n" pr (I.div (I.succ p300) (I.neg p120));
Printf.printf "(-(2^300+1)) / (-(2^120)) (trunc)\n = %a\n" pr (I.div (I.neg (I.succ p300)) (I.neg p120));
Printf.printf "2^120 / 2^300 (ceil)\n = %a\n" pr (I.cdiv p120 p300);
Printf.printf "max_int / 2 (ceil)\n = %a\n" pr (I.cdiv maxi p2);
Printf.printf "(2^300+1) / 2^120 (ceil)\n = %a\n" pr (I.cdiv (I.succ p300) p120);
Printf.printf "(-(2^300+1)) / 2^120 (ceil)\n = %a\n" pr (I.cdiv (I.neg (I.succ p300)) p120);
Printf.printf "(2^300+1) / (-(2^120)) (ceil)\n = %a\n" pr (I.cdiv (I.succ p300) (I.neg p120));
Printf.printf "(-(2^300+1)) / (-(2^120)) (ceil)\n = %a\n" pr (I.cdiv (I.neg (I.succ p300)) (I.neg p120));
Printf.printf "2^120 / 2^300 (floor)\n = %a\n" pr (I.fdiv p120 p300);
Printf.printf "max_int / 2 (floor)\n = %a\n" pr (I.fdiv maxi p2);
Printf.printf "(2^300+1) / 2^120 (floor)\n = %a\n" pr (I.fdiv (I.succ p300) p120);
Printf.printf "(-(2^300+1)) / 2^120 (floor)\n = %a\n" pr (I.fdiv (I.neg (I.succ p300)) p120);
Printf.printf "(2^300+1) / (-(2^120)) (floor)\n = %a\n" pr (I.fdiv (I.succ p300) (I.neg p120));
Printf.printf "(-(2^300+1)) / (-(2^120)) (floor)\n = %a\n" pr (I.fdiv (I.neg (I.succ p300)) (I.neg p120));
Printf.printf "2^120 %% 2^300\n = %a\n" pr (I.rem p120 p300);
Printf.printf "max_int %% 2\n = %a\n" pr (I.rem maxi p2);
Printf.printf "(2^300+1) %% 2^120\n = %a\n" pr (I.rem (I.succ p300) p120);
Printf.printf "(-(2^300+1)) %% 2^120\n = %a\n" pr (I.rem (I.neg (I.succ p300)) p120);
Printf.printf "(2^300+1) %% (-(2^120))\n = %a\n" pr (I.rem (I.succ p300) (I.neg p120));
Printf.printf "(-(2^300+1)) %% (-(2^120))\n = %a\n" pr (I.rem (I.neg (I.succ p300)) (I.neg p120));
Printf.printf "2^120 /,%% 2^300\n = %a\n" pr2 (I.div_rem p120 p300);
Printf.printf "max_int /,%% 2\n = %a\n" pr2 (I.div_rem maxi p2);
Printf.printf "(2^300+1) /,%% 2^120\n = %a\n" pr2 (I.div_rem (I.succ p300) p120);
Printf.printf "(-(2^300+1)) /,%% 2^120\n = %a\n" pr2 (I.div_rem (I.neg (I.succ p300)) p120);
Printf.printf "(2^300+1) /,%% (-(2^120))\n = %a\n" pr2 (I.div_rem (I.succ p300) (I.neg p120));
Printf.printf "(-(2^300+1)) /,%% (-(2^120))\n = %a\n" pr2 (I.div_rem (I.neg (I.succ p300)) (I.neg p120));
Printf.printf "1 & 2\n = %a\n" pr (I.logand I.one p2);
Printf.printf "1 & 2^300\n = %a\n" pr (I.logand I.one p300);
Printf.printf "2^120 & 2^300\n = %a\n" pr (I.logand p120 p300);
Printf.printf "2^300 & 2^120\n = %a\n" pr (I.logand p300 p120);
Printf.printf "2^300 & 2^300\n = %a\n" pr (I.logand p300 p300);
Printf.printf "2^300 & 0\n = %a\n" pr (I.logand p300 I.zero);
Printf.printf "-2^120 & 2^300\n = %a\n" pr (I.logand (I.neg p120) p300);
Printf.printf " 2^120 & -2^300\n = %a\n" pr (I.logand p120 (I.neg p300));
Printf.printf "-2^120 & -2^300\n = %a\n" pr (I.logand (I.neg p120) (I.neg p300));
Printf.printf "-2^300 & 2^120\n = %a\n" pr (I.logand (I.neg p300) p120);
Printf.printf " 2^300 & -2^120\n = %a\n" pr (I.logand p300 (I.neg p120));
Printf.printf "-2^300 & -2^120\n = %a\n" pr (I.logand (I.neg p300) (I.neg p120));
Printf.printf "1 | 2\n = %a\n" pr (I.logor I.one p2);
Printf.printf "1 | 2^300\n = %a\n" pr (I.logor I.one p300);
Printf.printf "2^120 | 2^300\n = %a\n" pr (I.logor p120 p300);
Printf.printf "2^300 | 2^120\n = %a\n" pr (I.logor p300 p120);
Printf.printf "2^300 | 2^300\n = %a\n" pr (I.logor p300 p300);
Printf.printf "2^300 | 0\n = %a\n" pr (I.logor p300 I.zero);
Printf.printf "-2^120 | 2^300\n = %a\n" pr (I.logor (I.neg p120) p300);
Printf.printf " 2^120 | -2^300\n = %a\n" pr (I.logor p120 (I.neg p300));
Printf.printf "-2^120 | -2^300\n = %a\n" pr (I.logor (I.neg p120) (I.neg p300));
Printf.printf "-2^300 | 2^120\n = %a\n" pr (I.logor (I.neg p300) p120);
Printf.printf " 2^300 | -2^120\n = %a\n" pr (I.logor p300 (I.neg p120));
Printf.printf "-2^300 | -2^120\n = %a\n" pr (I.logor (I.neg p300) (I.neg p120));
Printf.printf "1 ^ 2\n = %a\n" pr (I.logxor I.one p2);
Printf.printf "1 ^ 2^300\n = %a\n" pr (I.logxor I.one p300);
Printf.printf "2^120 ^ 2^300\n = %a\n" pr (I.logxor p120 p300);
Printf.printf "2^300 ^ 2^120\n = %a\n" pr (I.logxor p300 p120);
Printf.printf "2^300 ^ 2^300\n = %a\n" pr (I.logxor p300 p300);
Printf.printf "2^300 ^ 0\n = %a\n" pr (I.logxor p300 I.zero);
Printf.printf "-2^120 ^ 2^300\n = %a\n" pr (I.logxor (I.neg p120) p300);
Printf.printf " 2^120 ^ -2^300\n = %a\n" pr (I.logxor p120 (I.neg p300));
Printf.printf "-2^120 ^ -2^300\n = %a\n" pr (I.logxor (I.neg p120) (I.neg p300));
Printf.printf "-2^300 ^ 2^120\n = %a\n" pr (I.logxor (I.neg p300) p120);
Printf.printf " 2^300 ^ -2^120\n = %a\n" pr (I.logxor p300 (I.neg p120));
Printf.printf "-2^300 ^ -2^120\n = %a\n" pr (I.logxor (I.neg p300) (I.neg p120));
Printf.printf "~0\n = %a\n" pr (I.lognot I.zero);
Printf.printf "~1\n = %a\n" pr (I.lognot I.one);
Printf.printf "~2\n = %a\n" pr (I.lognot p2);
Printf.printf "~2^300\n = %a\n" pr (I.lognot p300);
Printf.printf "~(-1)\n = %a\n" pr (I.lognot I.minus_one);
Printf.printf "~(-2)\n = %a\n" pr (I.lognot (I.neg p2));
Printf.printf "~(-(2^300))\n = %a\n" pr (I.lognot (I.neg p300));
Printf.printf "0 >> 1\n = %a\n" pr (I.shift_right I.zero 1);
Printf.printf "0 >> 100\n = %a\n" pr (I.shift_right I.zero 100);
Printf.printf "2 >> 1\n = %a\n" pr (I.shift_right p2 1);
Printf.printf "2 >> 2\n = %a\n" pr (I.shift_right p2 2);
Printf.printf "2 >> 100\n = %a\n" pr (I.shift_right p2 100);
Printf.printf "2^300 >> 1\n = %a\n" pr (I.shift_right p300 1);
Printf.printf "2^300 >> 2\n = %a\n" pr (I.shift_right p300 2);
Printf.printf "2^300 >> 100\n = %a\n" pr (I.shift_right p300 100);
Printf.printf "2^300 >> 200\n = %a\n" pr (I.shift_right p300 200);
Printf.printf "2^300 >> 300\n = %a\n" pr (I.shift_right p300 300);
Printf.printf "2^300 >> 400\n = %a\n" pr (I.shift_right p300 400);
Printf.printf "-1 >> 1\n = %a\n" pr (I.shift_right I.minus_one 1);
Printf.printf "-2 >> 1\n = %a\n" pr (I.shift_right (I.neg p2) 1);
Printf.printf "-2 >> 2\n = %a\n" pr (I.shift_right (I.neg p2) 2);
Printf.printf "-2 >> 100\n = %a\n" pr (I.shift_right (I.neg p2) 100);
Printf.printf "-2^300 >> 1\n = %a\n" pr (I.shift_right (I.neg p300) 1);
Printf.printf "-2^300 >> 2\n = %a\n" pr (I.shift_right (I.neg p300) 2);
Printf.printf "-2^300 >> 100\n = %a\n" pr (I.shift_right (I.neg p300) 100);
Printf.printf "-2^300 >> 200\n = %a\n" pr (I.shift_right (I.neg p300) 200);
Printf.printf "-2^300 >> 300\n = %a\n" pr (I.shift_right (I.neg p300) 300);
Printf.printf "-2^300 >> 400\n = %a\n" pr (I.shift_right (I.neg p300) 400);
Printf.printf "0 >>0 1\n = %a\n" pr (I.shift_right_trunc I.zero 1);
Printf.printf "0 >>0 100\n = %a\n" pr (I.shift_right_trunc I.zero 100);
Printf.printf "2 >>0 1\n = %a\n" pr (I.shift_right_trunc p2 1);
Printf.printf "2 >>0 2\n = %a\n" pr (I.shift_right_trunc p2 2);
Printf.printf "2 >>0 100\n = %a\n" pr (I.shift_right_trunc p2 100);
Printf.printf "2^300 >>0 1\n = %a\n" pr (I.shift_right_trunc p300 1);
Printf.printf "2^300 >>0 2\n = %a\n" pr (I.shift_right_trunc p300 2);
Printf.printf "2^300 >>0 100\n = %a\n" pr (I.shift_right_trunc p300 100);
Printf.printf "2^300 >>0 200\n = %a\n" pr (I.shift_right_trunc p300 200);
Printf.printf "2^300 >>0 300\n = %a\n" pr (I.shift_right_trunc p300 300);
Printf.printf "2^300 >>0 400\n = %a\n" pr (I.shift_right_trunc p300 400);
Printf.printf "-1 >>0 1\n = %a\n" pr (I.shift_right_trunc I.minus_one 1);
Printf.printf "-2 >>0 1\n = %a\n" pr (I.shift_right_trunc (I.neg p2) 1);
Printf.printf "-2 >>0 2\n = %a\n" pr (I.shift_right_trunc (I.neg p2) 2);
Printf.printf "-2 >>0 100\n = %a\n" pr (I.shift_right_trunc (I.neg p2) 100);
Printf.printf "-2^300 >>0 1\n = %a\n" pr (I.shift_right_trunc (I.neg p300) 1);
Printf.printf "-2^300 >>0 2\n = %a\n" pr (I.shift_right_trunc (I.neg p300) 2);
Printf.printf "-2^300 >>0 100\n = %a\n" pr (I.shift_right_trunc (I.neg p300) 100);
Printf.printf "-2^300 >>0 200\n = %a\n" pr (I.shift_right_trunc (I.neg p300) 200);
Printf.printf "-2^300 >>0 300\n = %a\n" pr (I.shift_right_trunc (I.neg p300) 300);
Printf.printf "-2^300 >>0 400\n = %a\n" pr (I.shift_right_trunc (I.neg p300) 400);
Printf.printf "0 << 1\n = %a\n" pr (I.shift_left I.zero 1);
Printf.printf "0 << 100\n = %a\n" pr (I.shift_left I.zero 100);
Printf.printf "2 << 1\n = %a\n" pr (I.shift_left p2 1);
Printf.printf "2 << 32\n = %a\n" pr (I.shift_left p2 32);
Printf.printf "2 << 64\n = %a\n" pr (I.shift_left p2 64);
Printf.printf "2 << 299\n = %a\n" pr (I.shift_left p2 299);
Printf.printf "2^120 << 1\n = %a\n" pr (I.shift_left p120 1);
Printf.printf "2^120 << 180\n = %a\n" pr (I.shift_left p120 180);
Printf.printf "compare 1 2\n = %i\n" (I.compare I.one p2);
Printf.printf "compare 1 1\n = %i\n" (I.compare I.one I.one);
Printf.printf "compare 2 1\n = %i\n" (I.compare p2 I.one);
Printf.printf "compare 2^300 2^120\n = %i\n" (I.compare p300 p120);
Printf.printf "compare 2^120 2^120\n = %i\n" (I.compare p120 p120);
Printf.printf "compare 2^120 2^300\n = %i\n" (I.compare p120 p300);
Printf.printf "compare 2^121 2^120\n = %i\n" (I.compare p121 p120);
Printf.printf "compare 2^120 2^121\n = %i\n" (I.compare p120 p121);
Printf.printf "compare 2^300 -2^120\n = %i\n" (I.compare p300 (I.neg p120));
Printf.printf "compare 2^120 -2^120\n = %i\n" (I.compare p120 (I.neg p120));
Printf.printf "compare 2^120 -2^300\n = %i\n" (I.compare p120 (I.neg p300));
Printf.printf "compare -2^300 2^120\n = %i\n" (I.compare (I.neg p300) p120);
Printf.printf "compare -2^120 2^120\n = %i\n" (I.compare (I.neg p120) p120);
Printf.printf "compare -2^120 2^300\n = %i\n" (I.compare (I.neg p120) p300);
Printf.printf "compare -2^300 -2^120\n = %i\n" (I.compare (I.neg p300) (I.neg p120));
Printf.printf "compare -2^120 -2^120\n = %i\n" (I.compare (I.neg p120) (I.neg p120));
Printf.printf "compare -2^120 -2^300\n = %i\n" (I.compare (I.neg p120) (I.neg p300));
Printf.printf "equal 1 2\n = %B\n" (I.equal I.one p2);
Printf.printf "equal 1 1\n = %B\n" (I.equal I.one I.one);
Printf.printf "equal 2 1\n = %B\n" (I.equal p2 I.one);
Printf.printf "equal 2^300 2^120\n = %B\n" (I.equal p300 p120);
Printf.printf "equal 2^120 2^120\n = %B\n" (I.equal p120 p120);
Printf.printf "equal 2^120 2^300\n = %B\n" (I.equal p120 p300);
Printf.printf "equal 2^121 2^120\n = %B\n" (I.equal p121 p120);
Printf.printf "equal 2^120 2^121\n = %B\n" (I.equal p120 p121);
Printf.printf "equal 2^120 -2^120\n = %B\n" (I.equal p120 (I.neg p120));
Printf.printf "equal -2^120 2^120\n = %B\n" (I.equal (I.neg p120) p120);
Printf.printf "equal -2^120 -2^120\n = %B\n" (I.equal (I.neg p120) (I.neg p120));
Printf.printf "sign 0\n = %i\n" (I.sign I.zero);
Printf.printf "sign 1\n = %i\n" (I.sign I.one);
Printf.printf "sign -1\n = %i\n" (I.sign I.minus_one);
Printf.printf "sign 2^300\n = %i\n" (I.sign p300);
Printf.printf "sign -2^300\n = %i\n" (I.sign (I.neg p300));
Printf.printf "gcd 0 0\n = %a\n" pr (I.gcd I.zero I.zero);
Printf.printf "gcd 0 -137\n = %a\n" pr (I.gcd (I.of_int 0) (I.of_int (-137)));
Printf.printf "gcd 12 27\n = %a\n" pr (I.gcd (I.of_int 12) (I.of_int 27));
Printf.printf "gcd 27 12\n = %a\n" pr (I.gcd (I.of_int 27) (I.of_int 12));
Printf.printf "gcd 27 27\n = %a\n" pr (I.gcd (I.of_int 27) (I.of_int 27));
Printf.printf "gcd -12 27\n = %a\n" pr (I.gcd (I.of_int (-12)) (I.of_int 27));
Printf.printf "gcd 12 -27\n = %a\n" pr (I.gcd (I.of_int 12) (I.of_int (-27)));
Printf.printf "gcd -12 -27\n = %a\n" pr (I.gcd (I.of_int (-12)) (I.of_int (-27)));
Printf.printf "gcd 0 2^300\n = %a\n" pr (I.gcd (I.of_int 0) p300);
Printf.printf "gcd 2^120 2^300\n = %a\n" pr (I.gcd p120 p300);
Printf.printf "gcd 2^300 2^120\n = %a\n" pr (I.gcd p300 p120);
Printf.printf "gcd 0 -2^300\n = %a\n" pr (I.gcd (I.of_int 0) (I.neg p300));
Printf.printf "gcd 2^120 -2^300\n = %a\n" pr (I.gcd p120 (I.neg p300));
Printf.printf "gcd 2^300 -2^120\n = %a\n" pr (I.gcd p300 (I.neg p120));
Printf.printf "gcd -2^120 2^300\n = %a\n" pr (I.gcd (I.neg p120) p300);
Printf.printf "gcd -2^300 2^120\n = %a\n" pr (I.gcd (I.neg p300) p120);
Printf.printf "gcd -2^120 -2^300\n = %a\n" pr (I.gcd (I.neg p120) (I.neg p300));
Printf.printf "gcd -2^300 -2^120\n = %a\n" pr (I.gcd (I.neg p300) (I.neg p120));
Printf.printf "gcdext 12 27\n = %a\n" pr3 (I.gcdext (I.of_int 12) (I.of_int 27));
Printf.printf "gcdext 27 12\n = %a\n" pr3 (I.gcdext (I.of_int 27) (I.of_int 12));
Printf.printf "gcdext 27 27\n = %a\n" pr3 (I.gcdext (I.of_int 27) (I.of_int 27));
Printf.printf "gcdext -12 27\n = %a\n" pr3 (I.gcdext (I.of_int (-12)) (I.of_int 27));
Printf.printf "gcdext 12 -27\n = %a\n" pr3 (I.gcdext (I.of_int 12) (I.of_int (-27)));
Printf.printf "gcdext -12 -27\n = %a\n" pr3 (I.gcdext (I.of_int (-12)) (I.of_int (-27)));
Printf.printf "gcdext 2^120 2^300\n = %a\n" pr3 (I.gcdext p120 p300);
Printf.printf "gcdext 2^300 2^120\n = %a\n" pr3 (I.gcdext p300 p120);
Printf.printf "gcdext 12 0\n = %a\n" pr3 (I.gcdext (I.of_int 12) I.zero);
Printf.printf "gcdext 0 27\n = %a\n" pr3 (I.gcdext I.zero (I.of_int 27));
Printf.printf "gcdext -12 0\n = %a\n" pr3 (I.gcdext (I.of_int (-12)) I.zero);
Printf.printf "gcdext 0 -27\n = %a\n" pr3 (I.gcdext I.zero (I.of_int (-27)));
Printf.printf "gcdext 2^120 0\n = %a\n" pr3 (I.gcdext p120 I.zero);
Printf.printf "gcdext 0 2^300\n = %a\n" pr3 (I.gcdext I.zero p300);
Printf.printf "gcdext -2^120 0\n = %a\n" pr3 (I.gcdext (I.neg p120) I.zero);
Printf.printf "gcdext 0 -2^300\n = %a\n" pr3 (I.gcdext I.zero (I.neg p300));
Printf.printf "gcdext 0 0\n = %a\n" pr3 (I.gcdext I.zero I.zero);
Printf.printf "lcm 0 0 = %a\n" pr (I.lcm I.zero I.zero);
Printf.printf "lcm 10 12 = %a\n" pr (I.lcm (I.of_int 10) (I.of_int 12));
Printf.printf "lcm -10 12 = %a\n" pr (I.lcm (I.of_int (-10)) (I.of_int 12));
Printf.printf "lcm 10 -12 = %a\n" pr (I.lcm (I.of_int 10) (I.of_int (-12)));
Printf.printf "lcm -10 -12 = %a\n" pr (I.lcm (I.of_int (-10)) (I.of_int (-12)));
Printf.printf "lcm 0 12 = %a\n" pr (I.lcm I.zero (I.of_int 12));
Printf.printf "lcm 0 -12 = %a\n" pr (I.lcm I.zero (I.of_int (-12)));
Printf.printf "lcm 10 0 = %a\n" pr (I.lcm (I.of_int 10) I.zero);
Printf.printf "lcm -10 0 = %a\n" pr (I.lcm (I.of_int (-10)) I.zero);
Printf.printf "lcm 2^120 2^300 = %a\n" pr (I.lcm p120 p300);
Printf.printf "lcm 2^120 -2^300 = %a\n" pr (I.lcm p120 (I.neg p300));
Printf.printf "lcm -2^120 2^300 = %a\n" pr (I.lcm (I.neg p120) p300);
Printf.printf "lcm -2^120 -2^300 = %a\n" pr (I.lcm (I.neg p120) (I.neg p300));
Printf.printf "lcm 2^120 0 = %a\n" pr (I.lcm p120 I.zero);
Printf.printf "lcm -2^120 0 = %a\n" pr (I.lcm (I.neg p120) I.zero);
Printf.printf "is_odd 0\n = %b\n" (I.is_odd (Z.of_int 0));
Printf.printf "is_odd 1\n = %b\n" (I.is_odd (Z.of_int 1));
Printf.printf "is_odd 2\n = %b\n" (I.is_odd (Z.of_int 2));
Printf.printf "is_odd 3\n = %b\n" (I.is_odd (Z.of_int 3));
Printf.printf "is_odd 2^120\n = %b\n" (I.is_odd p120);
Printf.printf "is_odd 2^120+1\n = %b\n" (I.is_odd (Z.succ p120));
Printf.printf "is_odd 2^300\n = %b\n" (I.is_odd p300);
Printf.printf "is_odd 2^300+1\n = %b\n" (I.is_odd (Z.succ p300));
Printf.printf "sqrt 0\n = %a\n" pr (I.sqrt I.zero);
Printf.printf "sqrt 1\n = %a\n" pr (I.sqrt I.one);
Printf.printf "sqrt 2\n = %a\n" pr (I.sqrt p2);
Printf.printf "sqrt 2^120\n = %a\n" pr (I.sqrt p120);
Printf.printf "sqrt 2^121\n = %a\n" pr (I.sqrt p121);
Printf.printf "sqrt_rem 0\n = %a\n" pr2 (I.sqrt_rem I.zero);
Printf.printf "sqrt_rem 1\n = %a\n" pr2 (I.sqrt_rem I.one);
Printf.printf "sqrt_rem 2\n = %a\n" pr2 (I.sqrt_rem p2);
Printf.printf "sqrt_rem 2^120\n = %a\n" pr2 (I.sqrt_rem p120);
Printf.printf "sqrt_rem 2^121\n = %a\n" pr2 (I.sqrt_rem p121);
Printf.printf "popcount 0\n = %i\n" (I.popcount I.zero);
Printf.printf "popcount 1\n = %i\n" (I.popcount I.one);
Printf.printf "popcount 2\n = %i\n" (I.popcount p2);
Printf.printf "popcount max_int32\n = %i\n" (I.popcount maxi32);
Printf.printf "popcount 2^120\n = %i\n" (I.popcount p120);
Printf.printf "popcount (2^120-1)\n = %i\n" (I.popcount (I.pred p120));
Printf.printf "hamdist 0 0\n = %i\n" (I.hamdist I.zero I.zero);
Printf.printf "hamdist 0 1\n = %i\n" (I.hamdist I.zero I.one);
Printf.printf "hamdist 0 2^300\n = %i\n" (I.hamdist I.zero p300);
Printf.printf "hamdist 2^120 2^120\n = %i\n" (I.hamdist p120 p120);
Printf.printf "hamdist 2^120 (2^120-1)\n = %i\n" (I.hamdist p120 (I.pred p120));
Printf.printf "hamdist 2^120 2^300\n = %i\n" (I.hamdist p120 p300);
Printf.printf "hamdist (2^120-1) (2^300-1)\n = %i\n" (I.hamdist (I.pred p120) (I.pred p300));
Printf.printf "divisible 42 7\n = %B\n" (I.divisible (I.of_int 42) (I.of_int 7));
Printf.printf "divisible 43 7\n = %B\n" (I.divisible (I.of_int 43) (I.of_int 7));
Printf.printf "divisible 0 0\n = %B\n" (I.divisible I.zero I.zero);
Printf.printf "divisible 0 2^120\n = %B\n" (I.divisible I.zero p120);
Printf.printf "divisible 2 2^120\n = %B\n" (I.divisible (I.of_int 2) p120);
Printf.printf "divisible 2^300 2^120\n = %B\n" (I.divisible p300 p120);
Printf.printf "divisible (2^300-1) 32\n = %B\n" (I.divisible (I.pred p300) (I.of_int 32));
Printf.printf "divisible min_int (max_int+1)\n = %B\n" (I.divisible (I.of_int min_int) (I.succ (I.of_int max_int)));
Printf.printf "divisible (max_int+1) min_int\n = %B\n" (I.divisible (I.succ (I.of_int max_int)) (I.of_int min_int));
(* always 0 when not using custom blocks *)
Printf.printf "hash(2^120)\n = %i\n" (Hashtbl.hash p120);
Printf.printf "hash(2^121)\n = %i\n" (Hashtbl.hash p121);
Printf.printf "hash(2^300)\n = %i\n" (Hashtbl.hash p300);
(* fails if not using custom blocks *)
Printf.printf "2^120 = 2^300\n = %B\n" (p120 = p300);
Printf.printf "2^120 = 2^120\n = %B\n" (p120 = p120);
Printf.printf "2^120 = 2^120\n = %B\n" (p120 = (pow2 120));
Printf.printf "2^120 > 2^300\n = %B\n" (p120 > p300);
Printf.printf "2^120 < 2^300\n = %B\n" (p120 < p300);
Printf.printf "2^120 = 1\n = %B\n" (p120 = I.one);
(* In OCaml < 3.12.1, the order is not consistent with integers when
comparing mpn_ and ints with OCaml's polymorphic compare operator.
In OCaml >= 3.12.1, the results are consistent.
*)
Printf.printf "2^120 > 1\n = %B\n" (p120 > I.one);
Printf.printf "2^120 < 1\n = %B\n" (p120 < I.one);
Printf.printf "-2^120 > 1\n = %B\n" ((I.neg p120) > I.one);
Printf.printf "-2^120 < 1\n = %B\n" ((I.neg p120) < I.one);
Printf.printf "demarshal 2^120, 2^300, 1\n = %a\n" pr3
(Marshal.from_string (Marshal.to_string (p120,p300,I.one) []) 0);
Printf.printf "demarshal -2^120, -2^300, -1\n = %a\n" pr3
(Marshal.from_string (Marshal.to_string (I.neg p120,I.neg p300,I.minus_one) []) 0);
Printf.printf "format %%i 0 = /%s/\n" (I.format "%i" I.zero);
Printf.printf "format %%i 1 = /%s/\n" (I.format "%i" I.one);
Printf.printf "format %%i -1 = /%s/\n" (I.format "%i" I.minus_one);
Printf.printf "format %%i 2^30 = /%s/\n" (I.format "%i" p30);
Printf.printf "format %%i -2^30 = /%s/\n" (I.format "%i" (I.neg p30));
Printf.printf "format %% i 1 = /%s/\n" (I.format "% i" I.one);
Printf.printf "format %%+i 1 = /%s/\n" (I.format "%+i" I.one);
Printf.printf "format %%x 0 = /%s/\n" (I.format "%x" I.zero);
Printf.printf "format %%x 1 = /%s/\n" (I.format "%x" I.one);
Printf.printf "format %%x -1 = /%s/\n" (I.format "%x" I.minus_one);
Printf.printf "format %%x 2^30 = /%s/\n" (I.format "%x" p30);
Printf.printf "format %%x -2^30 = /%s/\n" (I.format "%x" (I.neg p30));
Printf.printf "format %%X 0 = /%s/\n" (I.format "%X" I.zero);
Printf.printf "format %%X 1 = /%s/\n" (I.format "%X" I.one);
Printf.printf "format %%X -1 = /%s/\n" (I.format "%X" I.minus_one);
Printf.printf "format %%X 2^30 = /%s/\n" (I.format "%X" p30);
Printf.printf "format %%X -2^30 = /%s/\n" (I.format "%X" (I.neg p30));
Printf.printf "format %%o 0 = /%s/\n" (I.format "%o" I.zero);
Printf.printf "format %%o 1 = /%s/\n" (I.format "%o" I.one);
Printf.printf "format %%o -1 = /%s/\n" (I.format "%o" I.minus_one);
Printf.printf "format %%o 2^30 = /%s/\n" (I.format "%o" p30);
Printf.printf "format %%o -2^30 = /%s/\n" (I.format "%o" (I.neg p30));
Printf.printf "format %%10i 0 = /%s/\n" (I.format "%10i" I.zero);
Printf.printf "format %%10i 1 = /%s/\n" (I.format "%10i" I.one);
Printf.printf "format %%10i -1 = /%s/\n" (I.format "%10i" I.minus_one);
Printf.printf "format %%10i 2^30 = /%s/\n" (I.format "%10i" p30);
Printf.printf "format %%10i -2^30 = /%s/\n" (I.format "%10i" (I.neg p30));
Printf.printf "format %%-10i 0 = /%s/\n" (I.format "%-10i" I.zero);
Printf.printf "format %%-10i 1 = /%s/\n" (I.format "%-10i" I.one);
Printf.printf "format %%-10i -1 = /%s/\n" (I.format "%-10i" I.minus_one);
Printf.printf "format %%-10i 2^30 = /%s/\n" (I.format "%-10i" p30);
Printf.printf "format %%-10i -2^30 = /%s/\n" (I.format "%-10i" (I.neg p30));
Printf.printf "format %%+10i 0 = /%s/\n" (I.format "%+10i" I.zero);
Printf.printf "format %%+10i 1 = /%s/\n" (I.format "%+10i" I.one);
Printf.printf "format %%+10i -1 = /%s/\n" (I.format "%+10i" I.minus_one);
Printf.printf "format %%+10i 2^30 = /%s/\n" (I.format "%+10i" p30);
Printf.printf "format %%+10i -2^30 = /%s/\n" (I.format "%+10i" (I.neg p30));
Printf.printf "format %% 10i 0 = /%s/\n" (I.format "% 10i" I.zero);
Printf.printf "format %% 10i 1 = /%s/\n" (I.format "% 10i" I.one);
Printf.printf "format %% 10i -1 = /%s/\n" (I.format "% 10i" I.minus_one);
Printf.printf "format %% 10i 2^30 = /%s/\n" (I.format "% 10i" p30);
Printf.printf "format %% 10i -2^30 = /%s/\n" (I.format "% 10i" (I.neg p30));
Printf.printf "format %%010i 0 = /%s/\n" (I.format "%010i" I.zero);
Printf.printf "format %%010i 1 = /%s/\n" (I.format "%010i" I.one);
Printf.printf "format %%010i -1 = /%s/\n" (I.format "%010i" I.minus_one);
Printf.printf "format %%010i 2^30 = /%s/\n" (I.format "%010i" p30);
Printf.printf "format %%010i -2^30 = /%s/\n" (I.format "%010i" (I.neg p30));
Printf.printf "format %%#x 0 = /%s/\n" (I.format "%#x" I.zero);
Printf.printf "format %%#x 1 = /%s/\n" (I.format "%#x" I.one);
Printf.printf "format %%#x -1 = /%s/\n" (I.format "%#x" I.minus_one);
Printf.printf "format %%#x 2^30 = /%s/\n" (I.format "%#x" p30);
Printf.printf "format %%#x -2^30 = /%s/\n" (I.format "%#x" (I.neg p30));
Printf.printf "format %%#X 0 = /%s/\n" (I.format "%#X" I.zero);
Printf.printf "format %%#X 1 = /%s/\n" (I.format "%#X" I.one);
Printf.printf "format %%#X -1 = /%s/\n" (I.format "%#X" I.minus_one);
Printf.printf "format %%#X 2^30 = /%s/\n" (I.format "%#X" p30);
Printf.printf "format %%#X -2^30 = /%s/\n" (I.format "%#X" (I.neg p30));
Printf.printf "format %%#o 0 = /%s/\n" (I.format "%#o" I.zero);
Printf.printf "format %%#o 1 = /%s/\n" (I.format "%#o" I.one);
Printf.printf "format %%#o -1 = /%s/\n" (I.format "%#o" I.minus_one);
Printf.printf "format %%#o 2^30 = /%s/\n" (I.format "%#o" p30);
Printf.printf "format %%#o -2^30 = /%s/\n" (I.format "%#o" (I.neg p30));
Printf.printf "format %%#10x 0 = /%s/\n" (I.format "%#10x" I.zero);
Printf.printf "format %%#10x 1 = /%s/\n" (I.format "%#10x" I.one);
Printf.printf "format %%#10x -1 = /%s/\n" (I.format "%#10x" I.minus_one);
Printf.printf "format %%#10x 2^30 = /%s/\n" (I.format "%#10x" p30);
Printf.printf "format %%#10x -2^30 = /%s/\n" (I.format "%#10x" (I.neg p30));
Printf.printf "format %%#10X 0 = /%s/\n" (I.format "%#10X" I.zero);
Printf.printf "format %%#10X 1 = /%s/\n" (I.format "%#10X" I.one);
Printf.printf "format %%#10X -1 = /%s/\n" (I.format "%#10X" I.minus_one);
Printf.printf "format %%#10X 2^30 = /%s/\n" (I.format "%#10X" p30);
Printf.printf "format %%#10X -2^30 = /%s/\n" (I.format "%#10X" (I.neg p30));
Printf.printf "format %%#10o 0 = /%s/\n" (I.format "%#10o" I.zero);
Printf.printf "format %%#10o 1 = /%s/\n" (I.format "%#10o" I.one);
Printf.printf "format %%#10o -1 = /%s/\n" (I.format "%#10o" I.minus_one);
Printf.printf "format %%#10o 2^30 = /%s/\n" (I.format "%#10o" p30);
Printf.printf "format %%#10o -2^30 = /%s/\n" (I.format "%#10o" (I.neg p30));
Printf.printf "format %%#-10x 0 = /%s/\n" (I.format "%#-10x" I.zero);
Printf.printf "format %%#-10x 1 = /%s/\n" (I.format "%#-10x" I.one);
Printf.printf "format %%#-10x -1 = /%s/\n" (I.format "%#-10x" I.minus_one);
Printf.printf "format %%#-10x 2^30 = /%s/\n" (I.format "%#-10x" p30);
Printf.printf "format %%#-10x -2^30 = /%s/\n" (I.format "%#-10x" (I.neg p30));
Printf.printf "format %%#-10X 0 = /%s/\n" (I.format "%#-10X" I.zero);
Printf.printf "format %%#-10X 1 = /%s/\n" (I.format "%#-10X" I.one);
Printf.printf "format %%#-10X -1 = /%s/\n" (I.format "%#-10X" I.minus_one);
Printf.printf "format %%#-10X 2^30 = /%s/\n" (I.format "%#-10X" p30);
Printf.printf "format %%#-10X -2^30 = /%s/\n" (I.format "%#-10X" (I.neg p30));
Printf.printf "format %%#-10o 0 = /%s/\n" (I.format "%#-10o" I.zero);
Printf.printf "format %%#-10o 1 = /%s/\n" (I.format "%#-10o" I.one);
Printf.printf "format %%#-10o -1 = /%s/\n" (I.format "%#-10o" I.minus_one);
Printf.printf "format %%#-10o 2^30 = /%s/\n" (I.format "%#-10o" p30);
Printf.printf "format %%#-10o -2^30 = /%s/\n" (I.format "%#-10o" (I.neg p30));
let extract_testdata =
let a = I.of_int 42
and b = I.of_int (-42)
and c = I.of_string "3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701" in
[a,0,1; a,0,5; a,0,32; a,0,64;
a,1,1; a,1,5; a,1,32; a,1,63; a,1,64; a,1,127; a,1,128;
a,69,12;
b,0,1; b,0,5; b,0,32; b,0,64;
b,1,1; b,1,5; b,1,32; b,1,63; b,1,64; b,1,127; b,1,128;
b,69,12;
c,0,1; c,0,64; c,128,1; c,128,5; c,131,32; c,175,63; c,277,123] in
List.iter chk_extract extract_testdata;
List.iter chk_signed_extract extract_testdata;
chk_bits I.zero;
chk_bits p2;
chk_bits (I.neg p2);
chk_bits p30;
chk_bits (I.neg p30);
chk_bits p62;
chk_bits (I.neg p62);
chk_bits p300;
chk_bits p120;
chk_bits p121;
chk_bits maxi;
chk_bits mini;
chk_bits maxi32;
chk_bits mini32;
chk_bits maxi64;
chk_bits mini64;
chk_bits maxni;
chk_bits minni;
List.iter chk_testbit [
I.zero; I.one; I.of_int (-42);
I.of_string "31415926535897932384626433832795028841971693993751058209749445923078164062862089986";
I.neg (I.shift_left (I.of_int 123456) 64);
];
List.iter chk_numbits_tz [
I.zero; I.one; I.of_int (-42);
I.shift_left (I.of_int 9999) 77;
I.neg (I.shift_left (I.of_int 123456) 64);
];
Printf.printf "random_bits 45 = %a\n"
pr (I.random_bits_gen ~fill:pr_bytes 45);
Printf.printf "random_bits 45 = %a\n"
pr (I.random_bits_gen ~fill:pr_bytes 45);
Printf.printf "random_bits 12 = %a\n"
pr (I.random_bits_gen ~fill:pr_bytes 12);
Printf.printf "random_int 123456 = %a\n"
pr (I.random_int_gen ~fill:pr_bytes (I.of_int 123456));
Printf.printf "random_int 9999999 = %a\n"
pr (I.random_int_gen ~fill:pr_bytes (I.of_int 9999999));
()
(* testing Q *)
(* gcd extended to: gcd x 0 = gcd 0 x = 0 *)
let gcd2 a b =
if Z.sign a = 0 then b
else if Z.sign b = 0 then a
else Z.gcd a b
(* check invariant *)
let check x =
assert (Z.sign x.Q.den >= 0);
assert (Z.compare (gcd2 x.Q.num x.Q.den) Z.one <= 0)
let t_list = [Q.zero;Q.one;Q.minus_one;Q.inf;Q.minus_inf;Q.undef]
let test1 msg op =
List.iter
(fun x ->
let r = op x in
check r;
Printf.printf "%s %s = %s\n" msg (Q.to_string x) (Q.to_string r)
) t_list
let test2 msg op =
List.iter
(fun x ->
List.iter
(fun y ->
let r = op x y in
check r;
Printf.printf "%s %s %s = %s\n" (Q.to_string x) msg (Q.to_string y) (Q.to_string r)
) t_list
) t_list
let test_Q () =
let _ = List.iter check t_list in
let _ = test1 "-" Q.neg in
let _ = test1 "1/" Q.inv in
let _ = test1 "abs" Q.abs in
let _ = test2 "+" Q.add in
let _ = test2 "-" Q.sub in
let _ = test2 "*" Q.mul in
let _ = test2 "/" Q.div in
let _ = test2 "* 1/" (fun a b -> Q.mul a (Q.inv b)) in
let _ = test1 "mul_2exp (1) " (fun a -> Q.mul_2exp a 1) in
let _ = test1 "mul_2exp (2) " (fun a -> Q.mul_2exp a 2) in
let _ = test1 "div_2exp (1) " (fun a -> Q.div_2exp a 1) in
let _ = test1 "div_2exp (2) " (fun a -> Q.div_2exp a 2) in
(* check simple identitites *)
List.iter
(fun x ->
assert (0 = Q.compare x (Q.div_2exp (Q.mul_2exp x 2) 2));
assert (0 = Q.compare x (Q.mul_2exp (Q.div_2exp x 2) 2));
List.iter
(fun y ->
Printf.printf "identity checking %s %s\n" (Q.to_string x) (Q.to_string y);
assert (0 = Q.compare (Q.add x y) (Q.add y x));
assert (0 = Q.compare (Q.sub x y) (Q.neg (Q.sub y x)));
assert (0 = Q.compare (Q.sub x y) (Q.add x (Q.neg y)));
assert (0 = Q.compare (Q.mul x y) (Q.mul y x));
assert (0 = Q.compare (Q.div x y) (Q.mul x (Q.inv y)));
) t_list
) t_list;
assert (Q.compare Q.undef Q.undef = 0);
assert (not (Q.equal Q.undef Q.undef));
assert (not (Q.lt Q.undef Q.undef));
assert (not (Q.leq Q.undef Q.undef));
assert (not (Q.gt Q.undef Q.undef));
assert (not (Q.geq Q.undef Q.undef))
(* main *)
let _ = test_Z()
let _ = test_Q()

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff