45 lines
1 KiB
Nix
45 lines
1 KiB
Nix
{ pkgs, lib ? pkgs.lib, ... }:
|
|
let
|
|
inherit (builtins) head tail isFloat isInt;
|
|
inherit (lib.strings) toInt match splitString;
|
|
floatComponents = f: splitString "." (toString f);
|
|
in
|
|
rec {
|
|
|
|
# Force a number to be a float (hacky but works)
|
|
ensureFloat = v:
|
|
assert (isInt v || isFloat v);
|
|
v + 0.1 - 0.1;
|
|
|
|
# Convert integer to float (hacky but it works)
|
|
fromInt = i:
|
|
assert isInt i;
|
|
ensureFloat i;
|
|
|
|
# Round float to upper integer
|
|
ceil = f:
|
|
let
|
|
comp = floatComponents f;
|
|
int = toInt (head comp);
|
|
inc = if match "[1-9][[:digit:]]*" (head (tail comp)) != null then 1 else 0;
|
|
in
|
|
assert(isFloat f);
|
|
int + inc;
|
|
|
|
# Round float to lower integer
|
|
floor = f:
|
|
let
|
|
int = toInt (head (floatComponents f));
|
|
in
|
|
assert(isFloat f);
|
|
int;
|
|
|
|
# Round float to closest integer
|
|
round = f:
|
|
let
|
|
comp = floatComponents (ensureFloat f);
|
|
int = toInt (head comp);
|
|
inc = if match "[5-9][[:digit:]]*" (head (tail comp)) != null then 1 else 0;
|
|
in
|
|
int + inc;
|
|
}
|