{ 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; }