mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-07 19:55:31 -05:00
Implement CCInt.floor_div and CCInt.rem
This commit is contained in:
parent
43bccceac7
commit
883eb611f0
2 changed files with 82 additions and 0 deletions
|
|
@ -37,6 +37,78 @@ let pow a b =
|
|||
pow 0 1 = 0
|
||||
*)
|
||||
|
||||
let floor_div a n =
|
||||
if a < 0 && n >= 0 then
|
||||
(a + 1) / n - 1
|
||||
else if a > 0 && n < 0 then
|
||||
(a - 1) / n - 1
|
||||
else
|
||||
a / n
|
||||
|
||||
(*$T
|
||||
(floor_div 3 5 = 0)
|
||||
(floor_div 5 5 = 1)
|
||||
(floor_div 12 5 = 2)
|
||||
(floor_div 0 5 = 0)
|
||||
(floor_div (-1) 5 = -1)
|
||||
(floor_div (-5) 5 = -1)
|
||||
(floor_div (-12) 5 = -3)
|
||||
|
||||
(floor_div 0 (-5) = 0)
|
||||
(floor_div 3 (-5) = -1)
|
||||
(floor_div 5 (-5) = -1)
|
||||
(floor_div 9 (-5) = -2)
|
||||
(floor_div (-2) (-5) = 0)
|
||||
(floor_div (-8) (-5) = 1)
|
||||
|
||||
try ignore (floor_div 12 0); false with Division_by_zero -> true
|
||||
try ignore (floor_div (-12) 0); false with Division_by_zero -> true
|
||||
*)
|
||||
|
||||
(*$Q
|
||||
(Q.pair Q.small_signed_int Q.pos_int) \
|
||||
(fun (n, m) -> floor_div n m = int_of_float @@ floor (float n /. float m))
|
||||
(Q.pair Q.small_signed_int Q.pos_int) \
|
||||
(fun (n, m) -> floor_div n (-m) = int_of_float @@ floor (float n /. float (-m)))
|
||||
*)
|
||||
|
||||
let rem a n =
|
||||
let y = a mod n in
|
||||
if (y < 0) <> (n < 0) && y <> 0 then
|
||||
y + n
|
||||
else
|
||||
y
|
||||
|
||||
(*$T
|
||||
(rem 3 5 = 3)
|
||||
(rem 5 5 = 0)
|
||||
(rem 9 5 = 4)
|
||||
(rem (-1) 5 = 4)
|
||||
(rem (-5) 5 = 0)
|
||||
(rem (-9) 5 = 1)
|
||||
(rem 0 5 = 0)
|
||||
|
||||
(rem 0 (-5) = 0)
|
||||
(rem 3 (-5) = -2)
|
||||
(rem 5 (-5) = 0)
|
||||
(rem 9 (-5) = -1)
|
||||
(rem (-2) (-5) = -2)
|
||||
(rem (-8) (-5) = -3)
|
||||
|
||||
try ignore (rem 12 0); false with Division_by_zero -> true
|
||||
try ignore (rem (-12) 0); false with Division_by_zero -> true
|
||||
*)
|
||||
|
||||
(*$Q
|
||||
(Q.pair Q.int Q.pos_int) (fun (n, m) -> let y = rem n m in y >= 0 && y < m)
|
||||
(Q.pair Q.int Q.pos_int) (fun (n, m) -> let y = rem n (-m) in y > (-m) && y <= 0)
|
||||
*)
|
||||
|
||||
(*$Q
|
||||
(Q.pair Q.int Q.pos_int) (fun (n, m) -> n = m * floor_div n m + rem n m)
|
||||
(Q.pair Q.int Q.pos_int) (fun (n, m) -> n = (-m) * floor_div n (-m) + rem n (-m))
|
||||
*)
|
||||
|
||||
type 'a printer = Format.formatter -> 'a -> unit
|
||||
type 'a random_gen = Random.State.t -> 'a
|
||||
type 'a sequence = ('a -> unit) -> unit
|
||||
|
|
|
|||
|
|
@ -23,6 +23,16 @@ val pow : t -> t -> t
|
|||
Raises [Invalid_argument] if [a = b = 0] or [b] < 0.
|
||||
@since 0.11 *)
|
||||
|
||||
val floor_div : t -> t -> t
|
||||
(** [floor_div a n] is integer division rounding towards negative infinity.
|
||||
It satisfies [a = m * floor_div a n + rem a n].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val rem : t -> t -> t
|
||||
(** [rem a n] is the remainder of dividing [a] by [n], with the same
|
||||
sign as [n].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
type 'a printer = Format.formatter -> 'a -> unit
|
||||
type 'a random_gen = Random.State.t -> 'a
|
||||
type 'a sequence = ('a -> unit) -> unit
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue