aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorinoas <mail@inoas.com>2022-10-10 11:55:21 +0200
committerLouis Pilfold <louis@lpil.uk>2022-10-10 19:42:33 +0100
commit8e8d5ac2a44b33ba3497a4f4b3e2719376ae01dc (patch)
tree75f948dcb1d084fc6b1964262b50872efea6ebdf
parent6c83aca79e8f9764ce41bfbd27b5478d0c9fa098 (diff)
downloadgleam_stdlib-8e8d5ac2a44b33ba3497a4f4b3e2719376ae01dc.tar.gz
gleam_stdlib-8e8d5ac2a44b33ba3497a4f4b3e2719376ae01dc.zip
port elixir's Integer.floor_div
-rw-r--r--src/gleam/int.gleam35
-rw-r--r--test/gleam/int_test.gleam27
2 files changed, 60 insertions, 2 deletions
diff --git a/src/gleam/int.gleam b/src/gleam/int.gleam
index d110c3f..6a30e60 100644
--- a/src/gleam/int.gleam
+++ b/src/gleam/int.gleam
@@ -520,3 +520,38 @@ pub fn divide(a: Int, by b: Int) -> Result(Int, Nil) {
b -> Ok(a / b)
}
}
+
+/// Performs a *floored* integer division, which means that the result will
+/// always be rounded towards negative infinity.
+///
+/// If you want to perform truncated integer division (rounding towards zero),
+/// use `int.divide()` or the `/` operator instead.
+///
+/// Returns division of the inputs as a `Result`.
+///
+/// ## Examples
+///
+/// ```gleam
+/// > floor_divide(1, 0)
+/// Error(Nil)
+///
+/// > floor_divide(5, 2)
+/// Ok(2)
+///
+/// > floor_divide(6, -4)
+/// Ok(-2)
+///
+/// > floor_divide(-99, 2)
+/// Ok(-50)
+/// ```
+///
+pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) {
+ case divisor {
+ 0 -> Error(Nil)
+ divisor ->
+ case dividend * divisor < 0 && dividend % divisor != 0 {
+ True -> Ok(dividend / divisor - 1)
+ False -> Ok(dividend / divisor)
+ }
+ }
+}
diff --git a/test/gleam/int_test.gleam b/test/gleam/int_test.gleam
index 71c526b..26e36ba 100644
--- a/test/gleam/int_test.gleam
+++ b/test/gleam/int_test.gleam
@@ -273,7 +273,7 @@ pub fn power_test() {
// int.power(-1, 0.5) is equivalent to int.square_root(-1) and should
// return an error as an imaginary number would otherwise have to be
- // returned
+ // returned
int.power(-1, 0.5)
|> should.equal(Error(Nil))
@@ -286,7 +286,7 @@ pub fn power_test() {
int.power(0, -1.0)
|> should.equal(Error(Nil))
- // Check that a negative base and exponent is fine as long as the
+ // Check that a negative base and exponent is fine as long as the
// exponent is not fractional
int.power(-2, -1.0)
|> should.equal(Ok(-0.5))
@@ -423,3 +423,26 @@ pub fn divide_test() {
int.divide(1, by: 0)
|> should.equal(Error(Nil))
}
+
+pub fn floor_divide_test() {
+ int.floor_divide(1, 1)
+ |> should.equal(Ok(1))
+
+ int.floor_divide(1, 0)
+ |> should.equal(Error(Nil))
+
+ int.floor_divide(0, by: 1)
+ |> should.equal(Ok(0))
+
+ int.floor_divide(1, by: 0)
+ |> should.equal(Error(Nil))
+
+ int.floor_divide(5, by: 2)
+ |> should.equal(Ok(2))
+
+ int.floor_divide(6, by: -4)
+ |> should.equal(Ok(-2))
+
+ int.floor_divide(-99, by: 2)
+ |> should.equal(Ok(-50))
+}