-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
add to standard library: parse floats #375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Depends on #405 |
I've got a naive implementation of this in my tick repo, lib/float.zig |
We have a robust implementation of this in zig now; it just needs a more complete bigint implementation (#405). It's a port of errol: https://github.com/marcandrysco/Errol You can see the compile errors we get when you try to print a floating point now: const io = @import("std").io;
pub fn main() -> %void {
%%io.stdout.printf("Hello, world!\n{}\n", f32(12.34));
}
hmm actually that's not what I was expecting. I think actually the bigint implementation may no longer be blocking this issue. |
Printing floats is basically working but there are bugs. I'm going to do some fuzz testing and see where the C errol code and zig port get different answers, then step them both side by side and see what happens differently. |
A wee test to trigger an edge case "integer overflow", just swap the comments on
It's near when the f64 no longer can represent the large integer value. zig 64-bit: u64=9007199254740990 -> f64=9.007199e18 -> u64=9007199254740990
zig 64-bit: u64=9007199254740991 -> f64=9.007199e18 -> u64=9007199254740991
zig 64-bit: u64=9007199254740992 -> f64=n/a -> u64=9007199254740992 workaround
zig 64-bit: u64=9007199254740993 -> f64=n/a -> u64=9007199254740992 workaround
zig 64-bit: u64=9007199254740994 -> f64=9.007199e18 -> u64=9007199254740994
zig 64-bit: u64=9007199254740995 -> f64=9.007199e18 -> u64=9007199254740996
zig 64-bit: u64=9007199254740996 -> f64=9.007199e18 -> u64=9007199254740996
C 64-bit: u64=9007199254740989 -> f64=9007199254740989.000000 -> u64=9007199254740989
C 64-bit: u64=9007199254740990 -> f64=9007199254740990.000000 -> u64=9007199254740990
C 64-bit: u64=9007199254740991 -> f64=9007199254740991.000000 -> u64=9007199254740991
C 64-bit: u64=9007199254740992 -> f64=9007199254740992.000000 -> u64=9007199254740992
C 64-bit: u64=9007199254740993 -> f64=9007199254740992.000000 -> u64=9007199254740992
C 64-bit: u64=9007199254740994 -> f64=9007199254740994.000000 -> u64=9007199254740994 |
Brought up in irc, but we currently have some problems on some simple cases too. Tested on latest master.
|
A more catastrophic case for reference.
|
I need to print floats, so I've been poking at this today and I have some improvements in this commit. Here's what I did
This has been working for me so far, but if I wanted to PR it, how do you think I should test it? |
Thanks for looking into this.
One idea: write some C code to generate random floats and print them with printf. Output the float values as well as the printed strings. Have Zig print the same float values and check if you get the same results. |
I'll pick up parsing IEEE-754 floating-point numbers from strings. |
Can we get a checklist of what needs to happen here? |
What needs to happen here is /// `bytes` is a utf-8 encoded string
pub fn parseFloat(comptime T: type, bytes: []const u8) !T {
// ...
} |
FYI, I've implemented ParseNumber which does both integers and floats and wrapped parseFloat(comptime T: type, bytes: []const u8) around it. I'd be glad to refactor it into a pull request if desired. And, of course, any other comments welcome. Some Examples:
|
FWIW LuaJIT has an implementation that might be worth copying: https://github.com/LuaJIT/LuaJIT/blob/b025b01c5b9d23f6218c7d72b7aafa3f1ab1e08a/src/lj_strscan.c |
Depends on #374
The text was updated successfully, but these errors were encountered: