aboutsummaryrefslogtreecommitdiff
path: root/kernel/uint63_amd64_63.ml
diff options
context:
space:
mode:
authorGuillaume Melquiond2019-07-29 21:24:11 +0200
committerGuillaume Melquiond2019-07-29 21:36:35 +0200
commit654254ca2e6ac94d3e0c62a127f92caff4b5938c (patch)
tree75f33644dc5c54b924185198cf93b42a2e68cb9c /kernel/uint63_amd64_63.ml
parentb3c870e5ea090028fb9292e14d77496e1b9c8061 (diff)
Use the precondition of diveucl_21 to avoid massaging the dividend.
All the implementations now return (0, 0) when the dividend is so large that the quotient would overflow.
Diffstat (limited to 'kernel/uint63_amd64_63.ml')
-rw-r--r--kernel/uint63_amd64_63.ml12
1 files changed, 7 insertions, 5 deletions
diff --git a/kernel/uint63_amd64_63.ml b/kernel/uint63_amd64_63.ml
index 1bb633d413..98560e8b95 100644
--- a/kernel/uint63_amd64_63.ml
+++ b/kernel/uint63_amd64_63.ml
@@ -95,13 +95,12 @@ let le (x : int) (y : int) =
[@@ocaml.inline always]
(* division of two numbers by one *)
-(* precondition: y <> 0 *)
-(* outputs: q % 2^63, r s.t. x = q * y + r, r < y *)
+(* precondition: xh < y *)
+(* outputs: q, r s.t. x = q * y + r, r < y *)
let div21 xh xl y =
- let y = to_uint64 y in
(* nh might temporarily grow as large as 2*y - 1 in the loop body,
so we store it as a 64-bit unsigned integer *)
- let nh = ref (Int64.rem (to_uint64 xh) y) in
+ let nh = ref xh in
let nl = ref xl in
let q = ref 0 in
for _i = 0 to 62 do
@@ -117,7 +116,10 @@ let div21 xh xl y =
done;
!q, Int64.to_int !nh
-let div21 xh xl y = if y = 0 then 0, 0 else div21 xh xl y
+let div21 xh xl y =
+ let xh = to_uint64 xh in
+ let y = to_uint64 y in
+ if Int64.compare y xh <= 0 then 0, 0 else div21 xh xl y
(* exact multiplication *)
(* TODO: check that none of these additions could be a logical or *)