zig
zig copied to clipboard
std.math: port `int_log10` from Rust
A straight forward port of int_log10
from the Rust standard library, including tests.
In theory, this makes it possible to accurately compute log10
of any integer, from u1
to u65535
. However, due to a compiler bug, currently it only gives accurate results up to u136
.
Even with limitations, the proposed implementation it's an improvement because currently the compiler segfaults when trying to use integers bigger than u128
and gives wrong results even when it works.
I've been learning Zig for 2 weeks, sorry for any mistakes or non idiomatic code.
Incidentally, that bug is soon going to be fixed :) https://github.com/jacobly0/zig/commit/c1d16a2b80e258a126ed496dab09a8a7c26f8468
Cool. I was thinking about this too. I saw that std.math.log10
accepted integers, but didn't advertise that there was a round-trip float conversion:
https://github.com/ziglang/zig/blob/36d47dd1991f0ccd7a9673075624f09500cc415e/lib/std/math/log10.zig#L13-L25
and so produced incorrect results for large-ish integers near a power of 10. The first such example is std.math.log10(999_999_999_999_998)
, which produces 15
instead of 14
(like 999_999_999_999_997
).
As a possible follow-up, given the accepted proposal for @log2
to work for integers (https://github.com/ziglang/zig/issues/13642), should @log10
work for integers too?
Just in case it's helpful/interesting for anybody reading, here's some resources that I'm aware of:
- https://internals.rust-lang.org/t/worth-optimizing-ilog10/18294 - Rust discussion of optimizing
ilog10
further (I'm not suggesting trying that now) - https://da-data.blogspot.com/2023/02/integer-log10-in-rust-and-c.html
- https://lemire.me/blog/2021/06/03/computing-the-number-of-digits-of-an-integer-even-faster/
Rust shipped this only recently, with 1.67.0 (2023-01-26):
- https://www.github.com/rust-lang/rust/issues/70887
- https://blog.rust-lang.org/2023/01/26/Rust-1.67.0.html#stabilized-apis
Those are some interesting resources for further optimizations, I wasn't aware of them.
Also, I wanted to improve @log10
to accept integers too because of #13642, but that is a more difficult task for a noob (too much compiler internals).
Seeing how this PR fails a lot of tests, postponing @log10
was the right call.
Due to #14816 being fixed I rebased and cleaned the history to try again. I also increased the test cases up to u512
which should be possible now.
It seems like only the LLVM backend can divide big ints for now...
I skipped some tests similar to #14482
Thank you, good work!