Quotient and remainder #
There are three main conventions for integer division,
referred here as the E, F, T rounding conventions.
All three pairs satisfy the identity x % y + (x / y) * y = x unconditionally,
and satisfy x / 0 = 0 and x % 0 = x.
T-rounding division #
div uses the ["T-rounding"][t-rounding]
(Truncation-rounding) convention, meaning that it rounds toward
zero. Also note that division by zero is defined to equal zero.
The relation between integer division and modulo is found in
Int.mod_add_div which states that
a % b + b * (a / b) = a, unconditionally.
[t-rounding]: https://dl.acm.org/doi/pdf/10.1145/128861.128862 [theo mod_add_div]: https://leanprover-community.github.io/mathlib4_docs/find/?pattern=Int.mod_add_div#doc
Examples:
#eval (7 : Int) / (0 : Int) -- 0
#eval (0 : Int) / (7 : Int) -- 0
#eval (12 : Int) / (6 : Int) -- 2
#eval (12 : Int) / (-6 : Int) -- -2
#eval (-12 : Int) / (6 : Int) -- -2
#eval (-12 : Int) / (-6 : Int) -- 2
#eval (12 : Int) / (7 : Int) -- 1
#eval (12 : Int) / (-7 : Int) -- -1
#eval (-12 : Int) / (7 : Int) -- -1
#eval (-12 : Int) / (-7 : Int) -- 1
Implemented by efficient native code.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Integer modulo. This function uses the
"T-rounding" (Truncation-rounding) convention
to pair with Int.div, meaning that a % b + b * (a / b) = a
unconditionally (see Int.mod_add_div). In
particular, a % 0 = a.
Examples:
#eval (7 : Int) % (0 : Int) -- 7
#eval (0 : Int) % (7 : Int) -- 0
#eval (12 : Int) % (6 : Int) -- 0
#eval (12 : Int) % (-6 : Int) -- 0
#eval (-12 : Int) % (6 : Int) -- 0
#eval (-12 : Int) % (-6 : Int) -- 0
#eval (12 : Int) % (7 : Int) -- 5
#eval (12 : Int) % (-7 : Int) -- 5
#eval (-12 : Int) % (7 : Int) -- 2
#eval (-12 : Int) % (-7 : Int) -- 2
Implemented by efficient native code.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Integer division. This version of division uses the F-rounding convention
(flooring division), in which Int.fdiv x y satisfies fdiv x y = floor (x / y)
and Int.fmod is the unique function satisfying fmod x y + (fdiv x y) * y = x.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Integer modulus. This version of Int.mod uses the F-rounding convention
(flooring division), in which Int.fdiv x y satisfies fdiv x y = floor (x / y)
and Int.fmod is the unique function satisfying fmod x y + (fdiv x y) * y = x.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Integer division. This version of Int.div uses the E-rounding convention
(euclidean division), in which Int.emod x y satisfies 0 ≤ mod x y < natAbs y for y ≠ 0
and Int.ediv is the unique function satisfying emod x y + (ediv x y) * y = x.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Integer modulus. This version of Int.mod uses the E-rounding convention
(euclidean division), in which Int.emod x y satisfies 0 ≤ emod x y < natAbs y for y ≠ 0
and Int.ediv is the unique function satisfying emod x y + (ediv x y) * y = x.
Equations
- x✝.emod x = match x✝, x with | Int.ofNat m, n => Int.ofNat (m % n.natAbs) | Int.negSucc m, n => Int.subNatNat n.natAbs (m % n.natAbs).succ
Instances For
The Div and Mod syntax uses ediv and emod for compatibility with SMTLIb and mathematical reasoning tends to be easier.
Equations
- Int.instDiv = { div := Int.ediv }
bmod ("balanced" mod) #
Balanced mod (and balanced div) are a division and modulus pair such
that b * (Int.bdiv a b) + Int.bmod a b = a and b/2 ≤ Int.bmod a b < b/2 for all a : Int and b > 0.
This is used in Omega as well as signed bitvectors.