Skip to content

Commit 8d13694

Browse files
committed
adding caml_int64.to_string
1 parent 4a4925f commit 8d13694

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

jscomp/runtime/caml_int64.ml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,54 @@ let rec of_float (x : float) : t =
341341
external log2 : float = "LN2" [@@bs.val] [@@bs.scope "Math"]
342342
external log : float -> float = "log" [@@bs.val] [@@bs.scope "Math"]
343343
external ceil : float -> float = "ceil" [@@bs.val] [@@bs.scope "Math"]
344+
external floor : float -> float = "floor" [@@bs.val] [@@bs.scope "Math"]
344345
(* external maxFloat : float -> float -> float = "Math.max" [@@bs.val] *)
345346

347+
(* either top 11 bits are all 0 or all 1
348+
when it is all 1, we need exclude -2^53
349+
*)
350+
let isSafeInteger (Int64{hi;lo}) =
351+
let top11Bits = hi >> 21 in
352+
top11Bits = 0n ||
353+
(top11Bits = -1n &&
354+
Pervasives.not (lo = 0n && hi = (0xff_e0_00_00n |~ 0n )))
355+
356+
external string_of_float : float -> string = "String" [@@bs.val]
357+
let rec to_string ( self : int64) =
358+
let (Int64{hi=self_hi;_} as self) = unsafe_of_int64 self in
359+
if isSafeInteger self then
360+
string_of_float (to_float self)
361+
else
362+
363+
if self_hi <0n then
364+
if eq self min_int then "-9223372036854775808"
365+
else "-" ^ to_string (unsafe_to_int64 (neg self))
366+
else (* large positive number *)
367+
let (Int64 {lo ; hi} as approx_div1) = (of_float (floor (to_float self /. 10.) )) in
368+
let (Int64 { lo = rem_lo ;hi = rem_hi} ) = (* rem should be a pretty small number *)
369+
self
370+
|. sub_aux ~lo:(lo << 3) ~hi:((lo>>>29) |~ (hi << 3))
371+
|. sub_aux ~lo:(lo << 1) ~hi: ((lo >>> 31) |~ (hi << 1))
372+
in
373+
if rem_lo =0n && rem_hi = 0n then to_string (unsafe_to_int64 approx_div1) ^ "0"
374+
else
375+
if rem_hi < 0n then
376+
(* let (Int64 {lo = rem_lo}) = neg rem in *)
377+
let rem_lo = to_unsigned ((lognot rem_lo +~ 1n ) & 0xffff_ffffn) |. Caml_nativeint_extern.to_float in
378+
let delta = (ceil (rem_lo /. 10.)) in
379+
let remainder = 10. *. delta -. rem_lo in
380+
to_string (unsafe_to_int64 (sub_lo approx_div1
381+
(Caml_nativeint_extern.of_float delta))) ^
382+
Caml_nativeint_extern.to_string (Caml_nativeint_extern.of_float remainder)
383+
else
384+
let rem_lo = Caml_nativeint_extern.to_float rem_lo in
385+
let delta = (floor (rem_lo /. 10.)) in
386+
let remainder = rem_lo -. 10. *. delta in
387+
to_string (unsafe_to_int64 (add_lo approx_div1 ((Caml_nativeint_extern.of_float delta)))) ^
388+
Caml_nativeint_extern.to_string (Caml_nativeint_extern.of_float remainder)
389+
390+
391+
346392
let rec div self other =
347393
match self, other with
348394
| _, Int64 {lo = 0n ; hi = 0n} ->

jscomp/runtime/caml_int64.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,4 @@ external unsafe_of_int64 : int64 -> t = "%identity"
9090
val div_mod : int64 -> int64 -> int64 * int64
9191
val to_hex : int64 -> string
9292
val discard_sign : int64 -> int64
93-
val to_string : t -> string
93+
val to_string : int64 -> string

0 commit comments

Comments
 (0)