floor
lib.floor
Primop
Docs pulled from | This Revision | 21 minutes ago
Nix manual
Takes 1 arguments
number
Rounds and converts number to the next lower NixInt value if possible, i.e. floor *number* <= *number* and
*number* - floor *number* < 1.
An evaluation error is thrown, if there exists no such NixInt value floor *number*.
Due to bugs in previous Nix versions an evaluation error might be thrown, if the datatype of number is
a NixInt and if *number* < -9007199254740992 or *number* > 9007199254740992.
If the datatype of number is neither a NixInt (signed 64-bit integer) nor a NixFloat (IEEE-754 double-precision floating-point number), an evaluation error will be thrown.
Noogle detected
Detected Type
floor :: Float -> Int
Implementation
This function is implemented in c++ and is part of the native nix runtime.
static void prim_floor(EvalState & state, const PosIdx pos, Value ** args, Value & v)
{
auto value = state.forceFloat(
*args[0], args[0]->determinePos(pos), "while evaluating the first argument passed to builtins.floor");
auto floorValue = floor(value);
bool isInt = args[0]->type() == nInt;
constexpr NixFloat int_min = std::numeric_limits<NixInt::Inner>::min(); // power of 2, so that no rounding occurs
if (floorValue >= int_min && floorValue < -int_min) {
v.mkInt(floorValue);
} else if (isInt) {
// a NixInt, e.g. INT64_MAX, can be rounded to -int_min due to the cast to NixFloat
state
.error<EvalError>(
"Due to a bug (see https://github.com/NixOS/nix/issues/12899) the NixInt argument %1% caused undefined behavior in previous Nix versions.\n\tFuture Nix versions might implement the correct behavior.",
args[0]->integer().value)
.atPos(pos)
.debugThrow();
} else {
state.error<EvalError>("NixFloat argument %1% is not in the range of NixInt", args[0]->fpoint())
.atPos(pos)
.debugThrow();
}
// `forceFloat` casts NixInt to NixFloat, but instead NixInt args shall be returned unmodified
if (isInt) {
auto arg = args[0]->integer();
auto res = v.integer();
if (arg != res) {
state
.error<EvalError>(
"Due to a bug (see https://github.com/NixOS/nix/issues/12899) a loss of precision occurred in previous Nix versions because the NixInt argument %1% was rounded to %2%.\n\tFuture Nix versions might implement the correct behavior.",
arg,
res)
.atPos(pos)
.debugThrow();
}
}
}
Implementation
The following is the current implementation of this function.
floor