diff options
author | inoas <mail@inoas.com> | 2022-10-10 11:55:21 +0200 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2022-10-10 19:42:33 +0100 |
commit | 8e8d5ac2a44b33ba3497a4f4b3e2719376ae01dc (patch) | |
tree | 75f948dcb1d084fc6b1964262b50872efea6ebdf | |
parent | 6c83aca79e8f9764ce41bfbd27b5478d0c9fa098 (diff) | |
download | gleam_stdlib-8e8d5ac2a44b33ba3497a4f4b3e2719376ae01dc.tar.gz gleam_stdlib-8e8d5ac2a44b33ba3497a4f4b3e2719376ae01dc.zip |
port elixir's Integer.floor_div
-rw-r--r-- | src/gleam/int.gleam | 35 | ||||
-rw-r--r-- | test/gleam/int_test.gleam | 27 |
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)) +} |