It would be nice to add round : F64, {decimals : I8 ?? 0} -> F64 (and for Dec too).
The decimals argument works in different ways across various languages. Some use step or precision. I like decimals, I find it clearer. I like I8 instead of U8 so that you can round to the nearest, say, 100, with 1234.56.round({decimals: -2}) == 1200.0.
(x * 100).round() / 100 also works (instead of x.round({decimals: 2}), but it doesn't handle edge cases (e.g., it crashes if x > Dec.highest / 100).
2 messages were moved here from #contributing > Track remaining builtins for the Zig compiler by Luke Boswell.
Rounding a Dev sounds helpful and would be well defined I think.
Would rounding a F32 or F64 need to be a close approximation because e.g. 0.1 isn't representable in binary?
Mmh, good point. If I'm not mistaken, this can only be a problem when the last digit is 5, for example 2.675.F64.round({decimals: 2}): this would return 2.67 instead of 2.68 because 2.675 cannot be represented with F64, so it's actually 2.674999.... That said, there would be no problem with 1.5.F64.round({}) since integer+1/2 can be represented perfectly in F64.
I suspect that this would rarely be an issue, since any application that cares deeply about every single decimal would use Dec. And we're talking about rounding up or down when the last digit is 5: it's ambiguous anyway.
Maybe a simple warning in the docs would suffice?
Alternatively:
round : F64, {bits : I8 ?? 0} -> F64
If you need rounding (currency is a use-case that comes to mind), is that an indication you ought to be using Dec? Wondering if it makes sense to implement these kinds of primitives for Dec only.
Rounding is also used for bucketing. It's useful in data science, or in gaming, etc. In these use cases, you don't need crazy precision, as long as the errors are (at least roughly) unbiased.
How does bucketing look with floats using the current API's? I have never done that kind of thing before
If the bucketize function takes a list of values and a list of boundaries, then you don't need round, only is_lt. Maybe not the best example. :sweat_smile:
Another example is displaying a F64 value, such 2.684876223 seconds, as "2.685s".
Or generating a stable hash key (e.g., for memoization).
I don't have a strong opinion on this, but I feel like adding round() to F64 is fairly harmless and it can be handy.
Rounding for presentation seems like a fairly important use case. E.g I am currently writing a test bench for some classifiers with Roc and will only want accuracy or other proportions to N decimal places, and the same for statistical tests and confidence values, and for graph axes. (Significant figures are sometimes useful too but I don't know of any language that provides it as a builtin).
I think the rounding for presentation use-case might require a dedicated API. For instance: suppose you want to show 2.8999 with to decimal places. Rounding will get you 2.9, but you want 2.90.
Last updated: Sep 03 2026 at 15:16 UTC