~aasg/nixexprs

d5dedb436245af2603ba5b8213b89808168f3b07 — Aluísio Augusto Silva Gonçalves 2 months ago a74d1f8
lib: Add math.rem

math.rem computes the remainder of a truncated division, in which the
sign of the remainder is that of the dividend.  It is the most popular
implementation of the % operator, according to Wikipedia [1].

I thought about writing a math.mod as well, but it seems that there are
several competing alternatives to that.  Knuth's floored division seems
popular, as well as Euclidean division.  So I'll add it when there is
actual need for it.

[1]: https://en.wikipedia.org/wiki/Modulo_operation#In_programming_languages
3 files changed, 34 insertions(+), 1 deletions(-)

M lib/default.nix
M lib/math.nix
M lib/tests.nix
M lib/default.nix => lib/default.nix +1 -1
@@ 20,7 20,7 @@ let
    inherit (lists) indexOf isSubsetOf;

    math = callLibs ./math.nix;
    inherit (math) abs pow;
    inherit (math) abs pow rem;

    strings = callLibs ./strings.nix;
    inherit (strings) capitalize parseHex;

M lib/math.nix => lib/math.nix +8 -0
@@ 25,4 25,12 @@ rec {
    assert e >= 0;
    assert e > 0 -> (abs result) >= (abs n);
    result;

  /* rem :: int -> int -> int
   *
   * Computes the remainder of the division of `n` by `d`, such that
   * `rem n d == n - (n / d) * d`.  The sign of the result is that of
   * the dividend `n`.
   */
  rem = n: d: n - d * (n / d);
}

M lib/tests.nix => lib/tests.nix +25 -0
@@ 228,6 228,31 @@ runTestsOrDieTrying {
    expected = -243;
  };

  testRem1 = {
    expr = rem 120 9;
    expected = 3;
  };

  testRem2 = {
    expr = rem (-120) 9;
    expected = -3;
  };

  testRem3 = {
    expr = rem 120 (-9);
    expected = 3;
  };

  testRem4 = {
    expr = rem 688258375 8765;
    expected = 688258375 - (688258375 / 8765) * 8765;
  };

  testRem5 = {
    expr = rem 688258375 (-620);
    expected = 688258375 - (688258375 / (-620)) * (-620);
  };

  ###########
  # strings #
  ###########