This is an automated email from the git hooks/post-receive script.

glondu pushed a commit to branch master
in repository ocaml-zarith.

commit f0827a1c06b2667dbdd8efd207be9e8261b0f13f
Author: Stephane Glondu <st...@glondu.net>
Date:   Fri Sep 22 15:08:34 2017 +0200

    New upstream version 1.5
---
 .gitignore       |  10 +++++
 Changes          |  13 +++++-
 META             |   2 +-
 Makefile         |  25 -----------
 README           | 130 -------------------------------------------------------
 README.md        | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 caml_z.c         |   6 +--
 project.mak      |   7 +--
 q.ml             |  36 ++++++++++++++-
 q.mli            |   5 +++
 tests/bi.ml      |  14 +++---
 tests/tofloat.ml |  80 ++++++++++++++++++++++++++--------
 z.mlip           |  52 +++++++++++++---------
 z.mlp            |  30 ++++++-------
 z_pp.pl          |   8 ++++
 15 files changed, 320 insertions(+), 224 deletions(-)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..afef917
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+*.a
+*.cm?
+*.cmxa
+*.cmxs
+*.exe
+*.o
+Makefile
+z.ml
+z.mli
+z_features.h
diff --git a/Changes b/Changes
index 7f16b4d..2ddfaa2 100644
--- a/Changes
+++ b/Changes
@@ -1,3 +1,14 @@
+Release 1.5 (2017-05-26):
+- Install all .cmx files, improving performance of clients and
+  avoiding a warning from OCaml 4.03 and up.
+- Z.of_float: fix a bug in the fast path [Richard Jones]
+  (See https://bugzilla.redhat.com/show_bug.cgi?id=1392247)
+- Improve compatibility with OCaml 4.03 and up
+  [Bernhard Schommer]
+- Overflow issue in Z.pow and Z.root with very large exponents (GPR#5)
+  [Andre Maroneze]
+- Added function Q.to_float.
+
 Release 1.4.1 (2015-11-09):
 - Fixed ml_z_of_substring_base and Z.of_substring [Thomas Braibant]
 - Integrated Opam fix for Perl scripts [Thomas Braibant]
@@ -12,7 +23,7 @@ Release 1.4 (2015-11-02):
 - Added Z.trailing_zeros.
 - Added Z.testbit, Z.is_even, Z.is_odd.
 - Added Z.numbits, Z.log2 and Z.log2up.
-- PR$1467: Z.hash is declared as "noalloc" [François Bobot]
+- PR#1467: Z.hash is declared as "noalloc" [François Bobot]
 - PR#1451: configure fix [Spiros Eliopoulos]
 - PR#1436: disable "(void)" trick for unused variables on Windows [Bernhard 
Schommer]
 - PR#1434: removed dependencies on printf & co when Z_PERFORM_CHECK is 0 
[Hannes Mehnert]
diff --git a/META b/META
index 854de4b..d2aeb02 100644
--- a/META
+++ b/META
@@ -1,5 +1,5 @@
 description = "Arbitrary precision integers"
 requires = ""
-version = "1.4.1"
+version = "1.5"
 archive(byte) = "zarith.cma"
 archive(native) = "zarith.cmxa"
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 7c4c31f..0000000
--- a/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-# generated by ./configure
-
-CC=gcc
-OCAMLC=ocamlc
-OCAMLOPT=ocamlopt
-OCAMLDEP=ocamldep
-OCAMLMKLIB=ocamlmklib
-OCAMLDOC=ocamldoc
-OCAMLFLAGS=
-OCAMLOPTFLAGS=
-OCAMLINC=
-CFLAGS=-I/home/mine/.opam/4.02.1/lib/ocaml  -DZ_OCAML_HASH 
-DZ_OCAML_COMPARE_EXT -DHAS_GMP -DZ_ELF -DZ_DOT_LABEL_PREFIX  -O3 -Wall -Wextra 
-I/home/mine/include -I/usr/local/include
-ASFLAGS=-DZ_OCAML_HASH -DZ_OCAML_COMPARE_EXT -DHAS_GMP -DZ_ELF 
-DZ_DOT_LABEL_PREFIX  
-LIBS=-L/home/mine/lib -L/usr/local/lib -lgmp
-ARCH=x86_64
-INSTALLDIR=/home/mine/.opam/4.02.1/lib
-AR=ar
-INSTALL=install
-OCAMLFIND=ocamlfind
-INSTMETH=findlib
-OBJSUFFIX=o
-HASOCAMLOPT=yes
-HASDYNLINK=yes
-
-include project.mak
diff --git a/README b/README
deleted file mode 100644
index 6f934b8..0000000
--- a/README
+++ /dev/null
@@ -1,130 +0,0 @@
->OVERVIEW:
-
-This library implements arithmetic and logical operations over
-arbitrary-precision integers.  
-
-The module is simply named "Z".  Its interface is similar to that of
-the Int32, Int64 and Nativeint modules from the OCaml standard
-library, with some additional functions.  See the file z.mlip for
-documentation.
-
-The implementation uses GMP (the GNU Multiple Precision arithmetic
-library) to compute over big integers. 
-However, small integers are represented as unboxed Caml integers, to save 
-space and improve performance. Big integers are allocated in the Caml heap, 
-bypassing GMP's memory management and achieving better GC behavior than e.g. 
-the MLGMP library.
-Computations on small integers use a special, faster path (coded in assembly
-for some platforms and functions) eschewing calls to GMP, while computations
-on large intergers use the low-level MPN functions from GMP.
-
-Arbitrary-precision integers can be compared correctly using OCaml's 
-polymorphic comparison operators (=, <, >, etc.). 
-This requires OCaml version 3.12.1 or later, though.
-
-Additional features include:
-- a module Q for rationals, built on top of Z (see q.mli)
-- a compatibility layer Big_int_Z that implements the same API as Big_int,
-but uses Z internally
-
-
-
-REQUIREMENTS:
-
-- OCaml, preferably version 3.12.1 or later.  
-(Earlier versions are usable but generic comparisons will misbehave.)
-- Either the GMP library or the MPIR library, including development files.
-- A gcc-compatible C compiler and assembler (other compilers may work).
-- The Perl programming language.
-- (optional) The Findlib package manager.
-
-
-INSTALLATION:
-
-1) First, run the "configure" script by typing:
-
-   ./configure
-
-2) It creates a Makefile, which can be invoked by:
-
-   make
-
-This builds native and bytecode versions of the library.
-
-3) The libraries are installed by typing:
-
-   make install
-
-or, if you install to a system location but are not an administrator
-
-   sudo make install
-
-If Findlib is detected, it is used to install files. 
-Otherwise, the files are copied to a zarith subdirectory of the directory 
-given by `ocamlc -where`.
-The libraries are named "zarith.cmxa" and "zarith.cma", and the Findlib module
-is named "zarith". 
-Compiling and linking with the library requires passing the "-I +zarith" 
-option to ocamlc / ocamlopt.
-The "configure" script has a few options. Use the "-help" option to get a
-list and short description of each option.
-
-4) (optional) 
-HTML API documentation is built (using ocamldoc) by the additional command
-
-  make doc
-
-Test programs are built by the additional command
-
-  make tests
-
-(but these are  not installed).
-
-
-
-LICENSE:
-
-This Library is distributed under the terms of the GNU Library General
-Public License version 2, with a special exception allowing unconstrained 
-static linking. 
-See LICENSE file for details.
-
-
-
-AUTHORS:
-
-Antoine Miné, ENS Paris.
-Xavier Leroy, INRIA Paris-Rocquencourt.
-Pascal Cuoq, CEA LIST.
-
-
-
-COPYRIGHT:
-
-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).
-
-
-
-CONTENTS:
-
-The source files are:
-* configure         - configuration script
-* caml_z.c          - C implementation of all functions
-* caml_z_*.S        - asm implementation for a few functions
-* z_pp.pl           - script to generate z.ml[i] from z.ml[i]p
-* z.ml[i]p          - templates used to generate z.ml[i]p
-* big_int_z.ml[i]   - wrapper to provide a Big_int compatible API to Z
-* q.ml[i]           - rational library, pure OCaml on top of Z
-* projet.mak        - builds Z, Q and the tests
-* tests/            - simple regression tests and benchmarks
-
-Note: z_pp.pl simply scans the asm file (if any) to see which functions have
-an asm implementation. It then fixes the external statements in .mlp and 
-.mlip accordingly.
-The argument to z_pp.pl is the suffix * of the caml_z_*.S to use (guessed by
-configure).
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9388897
--- /dev/null
+++ b/README.md
@@ -0,0 +1,126 @@
+# The Zarith library
+
+## OVERVIEW
+
+This library implements arithmetic and logical operations over
+arbitrary-precision integers.  
+
+The module is simply named `Z`.  Its interface is similar to that of
+the `Int32`, `Int64` and `Nativeint` modules from the OCaml standard
+library, with some additional functions.  See the file `z.mlip` for
+documentation.
+
+The implementation uses GMP (the GNU Multiple Precision arithmetic
+library) to compute over big integers. 
+However, small integers are represented as unboxed Caml integers, to save 
+space and improve performance. Big integers are allocated in the Caml heap, 
+bypassing GMP's memory management and achieving better GC behavior than e.g. 
+the MLGMP library.
+Computations on small integers use a special, faster path (coded in assembly
+for some platforms and functions) eschewing calls to GMP, while computations
+on large intergers use the low-level MPN functions from GMP.
+
+Arbitrary-precision integers can be compared correctly using OCaml's 
+polymorphic comparison operators (`=`, `<`, `>`, etc.). 
+This requires OCaml version 3.12.1 or later, though.
+
+Additional features include:
+* a module `Q` for rationals, built on top of `Z` (see `q.mli`)
+* a compatibility layer `Big_int_Z` that implements the same API as Big_int 
from the legacy `Num` library, but uses `Z` internally
+
+## REQUIREMENTS
+
+* OCaml, preferably version 3.12.1 or later.  (Earlier versions are usable but 
generic comparisons will misbehave.)
+* Either the GMP library or the MPIR library, including development files.
+* GCC or Clang or a gcc-compatible C compiler and assembler (other compilers 
may work).
+* The Perl programming language.
+* The Findlib package manager (optional, recommended).
+
+
+## INSTALLATION
+
+1) First, run the "configure" script by typing:
+```
+   ./configure
+```
+The `configure` script has a few options. Use the `-help` option to get a
+list and short description of each option.
+
+2) It creates a Makefile, which can be invoked by:
+```
+   make
+```
+This builds native and bytecode versions of the library.
+
+3) The libraries are installed by typing:
+```
+   make install
+```
+or, if you install to a system location but are not an administrator
+```
+   sudo make install
+```
+If Findlib is detected, it is used to install files. 
+Otherwise, the files are copied to a `zarith/` subdirectory of the directory 
+given by `ocamlc -where`.
+
+The libraries are named `zarith.cmxa` and `zarith.cma`, and the Findlib module
+is named `zarith`. 
+
+Compiling and linking with the library requires passing the `-I +zarith`
+option to `ocamlc` / `ocamlopt`, or the `-package zarith` option to 
`ocamlfind`.
+
+4) (optional, recommended) Test programs are built and run by the additional 
command
+```
+  make tests
+```
+(but these are  not installed).
+
+5) (optional) HTML API documentation is built (using `ocamldoc`) by the 
additional command
+```
+  make doc
+```
+
+## LICENSE
+
+This Library is distributed under the terms of the GNU Library General
+Public License version 2, with a special exception allowing unconstrained 
+static linking. 
+See LICENSE file for details.
+
+
+## AUTHORS
+
+* Antoine Miné, Université Pierre et Marie Curie, formerly ENS Paris.
+* Xavier Leroy, INRIA Paris-Rocquencourt.
+* Pascal Cuoq, CEA LIST.
+
+
+## COPYRIGHT
+
+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).
+
+
+## CONTENTS
+
+Source files        | Description
+--------------------|-----------------------------------------
+  configure         | configuration script
+  caml_z.c          | C implementation of all functions
+  caml_z_*.S        | asm implementation for a few functions
+  z_pp.pl           | script to generate z.ml[i] from z.ml[i]p
+  z.ml[i]p          | templates used to generate z.ml[i]p
+  big_int_z.ml[i]   | wrapper to provide a Big_int compatible API to Z
+  q.ml[i]           | rational library, pure OCaml on top of Z
+  projet.mak        | builds Z, Q and the tests
+  tests/            | simple regression tests and benchmarks
+
+Note: `z_pp.pl` simply scans the asm file (if any) to see which functions have
+an asm implementation. It then fixes the external statements in .mlp and 
+.mlip accordingly.
+The argument to `z_pp.pl` is the suffix `*` of the `caml_z_*.S` to use 
(guessed by configure).
diff --git a/caml_z.c b/caml_z.c
index b690a2a..5d258b9 100644
--- a/caml_z.c
+++ b/caml_z.c
@@ -521,7 +521,7 @@ CAMLprim value ml_z_of_float(value v)
   Z_MARK_OP;
   x = Double_val(v);
 #if Z_USE_NATINT
-  if (x >= Z_MIN_INT_FL && x <= Z_MAX_INT_FL) return Val_long(x);
+  if (x >= Z_MIN_INT_FL && x <= Z_MAX_INT_FL) return Val_long((intnat) x);
 #endif
   Z_MARK_SLOW;
 #ifdef ARCH_ALIGN_INT64
@@ -2713,7 +2713,7 @@ CAMLprim value ml_z_pow(value base, value exp)
   CAMLparam2(base,exp);
   CAMLlocal1(r);
   mpz_t mbase;
-  int e = Long_val(exp);
+  intnat e = Long_val(exp);
   if (e < 0) 
     caml_invalid_argument("Z.pow: exponent must be non-negative");
   ml_z_mpz_init_set_z(mbase, base);
@@ -2728,7 +2728,7 @@ CAMLprim value ml_z_root(value a, value b)
   CAMLparam2(a,b);
   CAMLlocal1(r);
   mpz_t ma;
-  int mb = Long_val(b);
+  intnat mb = Long_val(b);
   if (mb < 0) 
     caml_invalid_argument("Z.root: exponent must be non-negative");
   ml_z_mpz_init_set_z(ma, a);
diff --git a/project.mak b/project.mak
index 79d5750..4857feb 100644
--- a/project.mak
+++ b/project.mak
@@ -39,10 +39,11 @@ MLISRC = z.mli q.mli big_int_Z.mli
 AUTOGEN = z.ml z.mli z_features.h
 
 CMIOBJ = $(MLISRC:%.mli=%.cmi)
+CMXOBJ = $(MLISRC:%.mli=%.cmx)
 TOINSTALL := zarith.h zarith.cma libzarith.$(LIBSUFFIX) $(MLISRC) $(CMIOBJ)
 
 ifeq ($(HASOCAMLOPT),yes)
-TOINSTALL := $(TOINSTALL) zarith.$(LIBSUFFIX) zarith.cmxa
+TOINSTALL := $(TOINSTALL) zarith.$(LIBSUFFIX) zarith.cmxa $(CMXOBJ)
 endif
 
 ifeq ($(HASDYNLINK),yes)
@@ -65,7 +66,7 @@ zarith.cmxa zarith.$(LIBSUFFIX): $(MLSRC:%.ml=%.cmx)
        $(OCAMLMKLIB) -failsafe -o zarith $+ $(LIBS)
 
 zarith.cmxs: zarith.cmxa libzarith.$(LIBSUFFIX)
-       $(OCAMLOPT) -shared -o $@ -I . zarith.cmxa
+       $(OCAMLOPT) -shared -o $@ -I . zarith.cmxa -linkall
 
 libzarith.$(LIBSUFFIX) dllzarith.$(DLLSUFFIX): $(SSRC:%.S=%.$(OBJSUFFIX)) 
$(CSRC:%.c=%.$(OBJSUFFIX)) 
        $(OCAMLMKLIB) -failsafe -o zarith $+ $(LIBS)
@@ -132,7 +133,7 @@ clean:
        make -C tests clean
 
 depend: $(AUTOGEN)
-       $(OCAMLDEP) -native $(OCAMLINC) *.ml *.mli > depend
+       $(OCAMLDEP) -native $(OCAMLINC) $(MLSRC) $(MLISRC) > depend
 
 include depend
 
diff --git a/q.ml b/q.ml
index d6e5f6c..e7dfd81 100644
--- a/q.ml
+++ b/q.ml
@@ -189,7 +189,41 @@ let to_int64 x = Z.to_int64 (to_bigint x)
 
 let to_nativeint x = Z.to_nativeint (to_bigint x)
 
-
+let to_float x =
+  match classify x with
+  | ZERO -> 0.0
+  | INF  -> infinity
+  | MINF -> neg_infinity
+  | UNDEF -> nan
+  | NZERO ->
+    let p = x.num and q = x.den in
+    let np = Z.numbits p and nq = Z.numbits q in
+    if np <= 53 && nq <= 53 then
+      (* p and q convert to floats exactly; use FP division to get the
+         correctly-rounded result. *)
+      Int64.to_float (Z.to_int64 p) /. Int64.to_float (Z.to_int64 q)
+    else begin
+      (* |p| is in [2^(np-1), 2^np)
+         q is in [2^(nq-1), 2^nq)
+         hence |p/q| is in (2^(np-nq-1), 2^(np-nq+1)).
+         We define n such that |p/q*2^n| is in [2^54, 2^56).
+         >= 2^54 so that the round to odd technique applies.
+         < 2^56 so that the integral part is representable as an int64. *)
+      let n = 55 - (np - nq) in
+      (* Scaling p/q by 2^n *)
+      let (p', q') =
+        if n >= 0
+        then (Z.shift_left p n, q)
+        else (p, Z.shift_left q (-n)) in
+      (* Euclidean division of p' by q' *)
+      let (quo, rem) = Z.ediv_rem p' q' in
+      (* quo is the integral part of p/q*2^n
+         rem/q' is the fractional part. *)
+      (* Round quo to float *)
+      let f = Z.round_to_float quo (Z.sign rem = 0) in
+      (* Apply exponent *)
+      ldexp f (-n)
+    end
 
 (* operations *)
 (* ---------- *)
diff --git a/q.mli b/q.mli
index f398d37..c43ca1b 100644
--- a/q.mli
+++ b/q.mli
@@ -164,6 +164,11 @@ val to_nativeint: t -> nativeint
 val to_string: t -> string
 (** Converts to human-readable, decimal, [/]-separated rational. *)
 
+val to_float: t -> float
+(** Converts to a floating-point number, using the current 
+    floating-point rounding mode.  With the default rounding mode,
+    the result is the floating-point number closest to the given
+    rational; ties break to even mantissa. *)
 
 (** {1 Arithmetic operations} *)
 
diff --git a/tests/bi.ml b/tests/bi.ml
index 7d7b9ea..415d0ca 100644
--- a/tests/bi.ml
+++ b/tests/bi.ml
@@ -35,12 +35,16 @@ let random_int64 () =
 let random_int () = Int64.to_int (random_int64 ())
 
 let random_string () =
-  let s = String.create (1 + Random.int 200) in
-  for i = 0 to String.length s - 1 do
-    s.[i] <- Char.chr (48 + Random.int 10)
+  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;
-  if String.length s > 1 && Random.bool () then s.[0] <- '-';
-  s
+  Buffer.contents s
 
 
 (* list utility *)
diff --git a/tests/tofloat.ml b/tests/tofloat.ml
index 291c50d..511daa1 100644
--- a/tests/tofloat.ml
+++ b/tests/tofloat.ml
@@ -25,6 +25,14 @@ let test1 (mant: int64) (exp: int) =
     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
@@ -36,12 +44,7 @@ let testN numrounds =
   done;
   (* Some random int64 values scaled by some random power of 2 *)
   for i = 1 to numrounds do
-    let m1 = Random.bits() in           (* 30 bits *)
-    let m2 = Random.bits() in           (* 30 bits *)
-    let m3 = Random.bits() in
-    let m = Int64.(logor (of_int m1)
-                         (logor (shift_left (of_int m2) 30)
-                                (shift_left (of_int m3) 60))) in
+    let m = rnd64() in
     let exp = Random.int 1100 in        (* sometimes +inf will result *)
     if not (test1 m exp) then incr errors
   done;
@@ -55,38 +58,77 @@ let testN numrounds =
   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";
+  printf "Default rounding mode (Z)";
   testN numrounds;
+  printf "Default rounding mode (Q)";
+  testQN numrounds;
   if setround FE_TOWARDZERO then begin
-    printf "Round toward zero";
-    testN numrounds
+    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";
-    testN numrounds
+    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";
-    testN numrounds
+    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";
-    testN numrounds
+    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
-
-
-
-
diff --git a/z.mlip b/z.mlip
index 9cf13f8..fdddc7f 100644
--- a/z.mlip
+++ b/z.mlip
@@ -60,7 +60,7 @@ val one: t
 val minus_one: t
 (** The number -1. *)
 
-external of_int: int -> t = "ml_z_of_int" "noalloc"
+external of_int: int -> t = "ml_z_of_int" @NOALLOC
 (** Converts from a base integer. *)
 
 external of_int32: int32 -> t = "ml_z_of_int32"
@@ -74,7 +74,7 @@ external of_nativeint: nativeint -> t = "ml_z_of_nativeint"
 
 external of_float: float -> t = "ml_z_of_float"
 (** Converts from a floating-point value. 
-    The value is truncated.
+    The value is truncated (rounded towards zero).
     Raises [Overflow] on infinity and NaN arguments.
  *)
 
@@ -87,6 +87,8 @@ val of_string: string -> t
     represented, in hexadecimal, octal, or binary, respectively.
     Otherwise, base 10 is assumed.
     (Unlike C, a lone [0] prefix does not denote octal.)
+    Raises an [Invalid_argument] exception if the string is not a
+    syntactically correct representation of an integer.
  *)
 
 val of_substring : string -> pos:int -> len:int -> t
@@ -226,14 +228,14 @@ external shift_right_trunc: t -> int -> t = 
shift_right_trunc@ASM
     The second argument must be non-negative.
  *)
 
-external numbits: t -> int = "ml_z_numbits" "noalloc"
+external numbits: t -> int = "ml_z_numbits" @NOALLOC
 (** Returns the number of significant bits in the given number.
     If [x] is zero, [numbits x] returns 0.  Otherwise,
     [numbits x] returns a positive integer [n] such that
     [2^{n-1} <= |x| < 2^n].  Note that [numbits] is defined
     for negative arguments, and that [numbits (-x) = numbits x]. *)
 
-external trailing_zeros: t -> int = "ml_z_trailing_zeros" "noalloc"
+external trailing_zeros: t -> int = "ml_z_trailing_zeros" @NOALLOC
 (** Returns the number of trailing 0 bits in the given number.
     If [x] is zero, [trailing_zeros x] returns [max_int].
     Otherwise, [trailing_zeros x] returns a nonnegative integer [n]
@@ -266,16 +268,16 @@ external hamdist: t -> t -> int = "ml_z_hamdist"
  *)
 
 external to_int: t -> int = "ml_z_to_int"
-(** Converts to a base integer. May raise an [Overflow]. *)
+(** Converts to a base integer. May raise [Overflow]. *)
 
 external to_int32: t -> int32 = "ml_z_to_int32"
-(** Converts to a 32-bit integer. May raise an [Overflow]. *)
+(** Converts to a 32-bit integer. May raise [Overflow]. *)
 
 external to_int64: t -> int64 = "ml_z_to_int64"
 (** Converts to a 64-bit integer. May raise [Overflow]. *)
 
 external to_nativeint: t -> nativeint = "ml_z_to_nativeint"
-(** Converts to a native integer. May raise an [Overflow]. *)
+(** Converts to a native integer. May raise [Overflow]. *)
 
 val to_float: t -> float
 (** Converts to a floating-point value.
@@ -315,16 +317,16 @@ external format: string -> t -> string = "ml_z_format"
     are simply ignored (and not copied in the output).
  *)
 
-external fits_int: t -> bool = "ml_z_fits_int" "noalloc"
+external fits_int: t -> bool = "ml_z_fits_int" @NOALLOC
 (** Whether the argument fits in a regular [int]. *)
 
-external fits_int32: t -> bool = "ml_z_fits_int32" "noalloc"
+external fits_int32: t -> bool = "ml_z_fits_int32" @NOALLOC
 (** Whether the argument fits in an [int32]. *)
 
-external fits_int64: t -> bool = "ml_z_fits_int64" "noalloc"
+external fits_int64: t -> bool = "ml_z_fits_int64" @NOALLOC
 (** Whether the argument fits in an [int64]. *)
 
-external fits_nativeint: t -> bool = "ml_z_fits_nativeint" "noalloc"
+external fits_nativeint: t -> bool = "ml_z_fits_nativeint" @NOALLOC
 (** Whether the argument fits in a [nativeint]. *)
 
 
@@ -353,7 +355,7 @@ val pp_print: Format.formatter -> t -> unit
 
 (** {1 Ordering} *)
 
-external compare: t -> t -> int = "ml_z_compare" "noalloc"
+external compare: t -> t -> int = "ml_z_compare" @NOALLOC
 (** Comparison.  [compare x y] returns 0 if [x] equals [y],
     -1 if [x] is smaller than [y], and 1 if [x] is greater than [y].
 
@@ -361,7 +363,7 @@ external compare: t -> t -> int = "ml_z_compare" "noalloc"
     only on OCaml 3.12.1 and later versions.
  *)
 
-external equal: t -> t -> bool = "ml_z_equal" "noalloc"
+external equal: t -> t -> bool = "ml_z_equal" @NOALLOC
 (** Equality test. *)
 
 val leq: t -> t -> bool
@@ -376,7 +378,7 @@ val lt: t -> t -> bool
 val gt: t -> t -> bool
 (** Greater than (and not equal). *)
 
-external sign: t -> int = "ml_z_sign" "noalloc"
+external sign: t -> int = "ml_z_sign" @NOALLOC
 (** Returns -1, 0, or 1 when the argument is respectively negative, null, or
     positive.
  *)
@@ -393,7 +395,7 @@ val is_even: t -> bool
 val is_odd: t -> bool
 (** Returns true if the argument is odd, false if even. *)
 
-external hash: t -> int = "ml_z_hash" "noalloc"
+external hash: t -> int = "ml_z_hash" @NOALLOC
 (** Hashes a number.
     This functions gives the same result as OCaml's polymorphic hashing
     function.
@@ -410,10 +412,12 @@ external gcd: t -> t -> t = "ml_z_gcd"
 *)
 
 val gcdext: t -> t -> (t * t * t)
-(** [gcd_ext u v] returns [(g,s,t)]  where [g] is the greatest common divisor
+(** [gcdext u v] returns [(g,s,t)]  where [g] is the greatest common divisor
     and [g=us+vt].
-    [g] is always positive.
+    [g] is always positive.      
     Raises a [Division_by_zero] is either argument is null.
+
+    Note: the function is based on the GMP [mpn_gcdext] function. The exact 
choice of [s] and [t] such that [g=us+vt] is not specified, as it may vary from 
a version of GMP to another (it has changed notably in GMP 4.3.0 and 4.3.1).
  *)
 
 val lcm: t -> t -> t
@@ -469,7 +473,8 @@ external pow: t -> int -> t = "ml_z_pow"
  *)
 
 external sqrt: t -> t = "ml_z_sqrt"
-(** Returns the square root. The result is truncated. 
+(** Returns the square root. The result is truncated (rounded down
+    to an integer).
     Raises an [Invalid_argument] on negative arguments.
  *)
 
@@ -503,7 +508,7 @@ val log2up: t -> int
 
 (** {1 Representation} *)
 
-external size: t -> int = "ml_z_size" "noalloc"
+external size: t -> int = "ml_z_size" @NOALLOC
 (** Returns the number of machine words used to represent the number. *)
 
 external extract: t -> int -> int -> t = "ml_z_extract"
@@ -517,7 +522,7 @@ val signed_extract: t -> int -> int -> t
 (** [signed_extract a off len] extracts bits [off] to [off]+[len]-1 of [b],
     as [extract] does, then sign-extends bit [len-1] of the result
     (that is, bit [off + len - 1] of [a]).  The result is between
-    [- 2{^[len]-1}] (included) and [2{^[len]-1}] excluded, 
+    [- 2{^[len]-1}] (included) and [2{^[len]-1}] (excluded), 
     and equal to [extract a off len] modulo [2{^len}].
  *)
 
@@ -598,7 +603,7 @@ external (lsl): t -> int -> t = shift_left@ASM
 external (asr): t -> int -> t = shift_right@ASM
 (** Bit-wise shift to the right [shift_right]. *)
 
-external (~$): int -> t = "ml_z_of_int" "noalloc"
+external (~$): int -> t = "ml_z_of_int" @NOALLOC
 (** Conversion from [int] [of_int]. *)
 
 external ( ** ): t -> int -> t = "ml_z_pow"
@@ -608,3 +613,8 @@ external ( ** ): t -> int -> t = "ml_z_pow"
 
 val version: string
 (** Library version (this file refers to version [@VERSION]). *)
+
+(**/**)
+
+(** For internal use in module [Q]. *)
+val round_to_float: t -> bool -> float
diff --git a/z.mlp b/z.mlp
index ee7b8f5..58763de 100644
--- a/z.mlp
+++ b/z.mlp
@@ -47,7 +47,7 @@ external lognot: t -> t = lognot@ASM
 external shift_left: t -> int -> t = shift_left@ASM
 external shift_right: t -> int -> t = shift_right@ASM
 external shift_right_trunc: t -> int -> t = shift_right_trunc@ASM
-external of_int: int -> t = "ml_z_of_int" "noalloc"
+external of_int: int -> t = "ml_z_of_int" @NOALLOC
 external of_int32: int32 -> t = "ml_z_of_int32"
 external of_int64: int64 -> t = "ml_z_of_int64"
 external of_nativeint: nativeint -> t = "ml_z_of_nativeint"
@@ -58,22 +58,22 @@ external to_int64: t -> int64 = "ml_z_to_int64"
 external to_nativeint: t -> nativeint = "ml_z_to_nativeint"
 external format: string -> t -> string = "ml_z_format"
 external of_substring_base: int -> string -> pos:int -> len:int -> t = 
"ml_z_of_substring_base"
-external compare: t -> t -> int = "ml_z_compare" "noalloc"
-external equal: t -> t -> bool = "ml_z_equal" "noalloc"
-external sign: t -> int = "ml_z_sign" "noalloc"
+external compare: t -> t -> int = "ml_z_compare" @NOALLOC
+external equal: t -> t -> bool = "ml_z_equal" @NOALLOC
+external sign: t -> int = "ml_z_sign" @NOALLOC
 external gcd: t -> t -> t = "ml_z_gcd"
 external gcdext_intern: t -> t -> (t * t * bool) = "ml_z_gcdext_intern"
 external sqrt: t -> t = "ml_z_sqrt"
 external sqrt_rem: t -> (t * t) = "ml_z_sqrt_rem"
-external numbits: t -> int = "ml_z_numbits" "noalloc"
-external trailing_zeros: t -> int = "ml_z_trailing_zeros" "noalloc"
+external numbits: t -> int = "ml_z_numbits" @NOALLOC
+external trailing_zeros: t -> int = "ml_z_trailing_zeros" @NOALLOC
 external popcount: t -> int = "ml_z_popcount"
 external hamdist: t -> t -> int = "ml_z_hamdist"
-external size: t -> int = "ml_z_size" "noalloc"
-external fits_int: t -> bool = "ml_z_fits_int" "noalloc"
-external fits_int32: t -> bool = "ml_z_fits_int32" "noalloc"
-external fits_int64: t -> bool = "ml_z_fits_int64" "noalloc"
-external fits_nativeint: t -> bool = "ml_z_fits_nativeint" "noalloc"
+external size: t -> int = "ml_z_size" @NOALLOC
+external fits_int: t -> bool = "ml_z_fits_int" @NOALLOC
+external fits_int32: t -> bool = "ml_z_fits_int32" @NOALLOC
+external fits_int64: t -> bool = "ml_z_fits_int64" @NOALLOC
+external fits_nativeint: t -> bool = "ml_z_fits_nativeint" @NOALLOC
 external extract: t -> int -> int -> t = "ml_z_extract"
 external powm: t -> t -> t -> t = "ml_z_powm"
 external pow: t -> int -> t = "ml_z_pow"
@@ -85,7 +85,7 @@ external perfect_power: t -> bool = "ml_z_perfect_power"
 external perfect_square: t -> bool = "ml_z_perfect_square"
 external probab_prime: t -> int -> int = "ml_z_probab_prime"
 external nextprime: t -> t = "ml_z_nextprime"
-external hash: t -> int = "ml_z_hash" "noalloc"
+external hash: t -> int = "ml_z_hash" @NOALLOC
 external to_bits: t -> string = "ml_z_to_bits"
 external of_bits: string -> t = "ml_z_of_bits"
 
@@ -108,7 +108,7 @@ let of_substring = of_substring_base 0
 let of_string_base base s = of_substring_base base s ~pos:0 
~len:(String.length s)
 
 let ediv_rem a b =
-  (* we have a = a * b + r, but [Big_int]'s remainder satisfies 0 <= r < |b|,
+  (* we have a = q * b + r, but [Big_int]'s remainder satisfies 0 <= r < |b|,
      while [Z]'s remainder satisfies -|b| < r < |b| and sign(r) = sign(a)
    *)
    let q,r = div_rem a b in
@@ -132,7 +132,7 @@ let lcm u v =
   let g = gcd u v in
   abs (mul (divexact u g) v)
 
-external testbit_internal: t -> int -> bool = "ml_z_testbit" "noalloc"
+external testbit_internal: t -> int -> bool = "ml_z_testbit" @NOALLOC
 let testbit x n =
   if n >= 0 then testbit_internal x n else invalid_arg "Z.testbit"
 (* The test [n >= 0] is done in Caml rather than in the C stub code
@@ -213,7 +213,7 @@ external (lxor): t -> t -> t = logxor@ASM
 external (~!): t -> t = lognot@ASM
 external (lsl): t -> int -> t = shift_left@ASM
 external (asr): t -> int -> t = shift_right@ASM
-external (~$): int -> t = "ml_z_of_int" "noalloc"
+external (~$): int -> t = "ml_z_of_int" @NOALLOC
 external ( ** ): t -> int -> t = "ml_z_pow"
 
 let version = @VERSION
diff --git a/z_pp.pl b/z_pp.pl
index ff10581..48a163a 100755
--- a/z_pp.pl
+++ b/z_pp.pl
@@ -25,6 +25,13 @@ die "Usage: './z_pp.pl architecture'" unless $#ARGV==0;
 $v = `grep version META`;
 ($ver) = $v =~ /version\s*=\s*(\S+)/;
 
+$ov = `ocamlc -version`;
+($major,$minor,$extra) = split(/\./, $ov, 3);
+if ($major > 4 || ($major == 4 && $minor >= 3)) {
+    $noalloc = "[\@\@noalloc]";
+} else {
+    $noalloc = "\"noalloc\"";
+}
 
 # scan assembly
 
@@ -64,6 +71,7 @@ sub doml {
             $l =~ s/$f\@ASM/$r/g;
         }
         $l =~ s/\@VERSION/$ver/;
+        $l =~ s/\@NOALLOC/$noalloc/;
         print O "$l";
     }
     close F;

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-ocaml-maint/packages/ocaml-zarith.git

_______________________________________________
Pkg-ocaml-maint-commits mailing list
Pkg-ocaml-maint-commits@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-ocaml-maint-commits

Reply via email to