Open ianprime0509 opened 1 month ago
Perhaps this is a bit of a tangent, but to comment on your specific example with std.math.nan
, maybe it would be better to define std.matn.nan
not as a function, but as a comptime float to begin with. You could also say the same for std.math.inf
Eg. @TypeOf(std.math.nan) == comptime_float
, and instead of using const x = std.math.nan(f32)
, use const x: f32 = std.math.nan
.
I can't really think of a substantial downside to this, nan
and inf
are after all comptime known float values, so it would not only be more concise, but also more clear and intuitive
The motivation behind this proposal is the analysis done in https://github.com/ziglang/zig/issues/21198#issuecomment-2308994913, with the goal of defining exactly how
comptime_float
should behave given conflicting implementation details and documentation.Background
The language reference has this to say about
comptime_float
:As explained in https://github.com/ziglang/zig/issues/2794#issuecomment-507427285, one reason for
comptime_float
to exist rather than just defining all floating-point literals to be comptime-knownf128
s is thatcomptime_float
may implicitly cast to other floating point types even if precision is lost. https://github.com/ziglang/zig/issues/5780#issuecomment-653332425 also solidified the connection between the implementation ofcomptime_float
and the capabilities off128
by reaffirming the above quote from the langref.Despite this, there are some other differences in today's Zig between
comptime_float
andf128
which are not limited to implicit casting behavior (test remarks below are as of Zig 0.14.0-dev.1304+7d54c62c8):The first two sets of discrepancies are included in the current compiler test suite (
0.0 / 0.0
,comptime_float / 0.0
error), which is why this is a proposal rather than a bug fix; evidently, some other behavior was intended at some point.Proposed behavior
All arithmetic operations with
comptime_float
should behave as if they were done with comptime-knownf128
. That is, the test above should be updated to the following:As the updated test suggests, accepting this proposal could also allow the float functions
std.math
(such asstd.math.isInf
) to be expanded to work withcomptime_float
by internally casting to/fromf128
, without concern that the semantics might be different. The formatted float printing logic already does this today: https://github.com/ziglang/zig/blob/7d54c62c8a55240bbe144ab03c78573a344598ce/lib/std/fmt/format_float.zig#L57-L58Alternatives and follow-up changes
Signaling NaNs
This proposal makes no comment on the behavior of "signaling NaN", since as far as I can tell, Zig is currently lacking any builtins or functions to interact with the floating point environment (and frankly I lack the expertise to make an informed proposal on what such support should look like). If this proposal is accepted, then any future proposal to clarify or expand the behavior of signaling NaNs in Zig should comment on the behavior of signaling NaNs at comptime, and the behavior of comptime-known
f128
andcomptime_float
should be identical.Restricted
comptime_float
The existing behavior of treating
1.0 / 0.0
as a compile error suggests thatcomptime_float
may have originally been intended as not justf128
, butf128
with no infinities or NaNs. If this is true, and if this still intended going forward, it will be necessary to clarify and fix implementation ofcomptime_float
in that direction, and document it as the expected behavior. For example, as it is now, despite1.0 / 0.0
being banned, it is trivial to createcomptime_float
infinities and NaNs by implicitly casting fromf128
or another float type.I can't think of any reason for
0.0 / 0.0 == 0.0
, though; in a universe wherecomptime_float
does not include infinities or NaNs,0.0 / 0.0
should be a compile error just like1.0 / 0.0
.std.math
support forcomptime_float
As mentioned in the proposed behavior section, if this is accepted and implemented, every
std.math
function which supportsf128
could easily be updated to supportcomptime_float
. For example,comptime_float
NaNs could be produced usingstd.math.nan(comptime_float)
.