Uh oh!
There was an error while loading. Please reload this page.
Add std.fmt.formatDuration and std.fmt.duration - #7297
Conversation
`formatDuration` works on a writer, and `duration` wraps a u64 to allow pleasant injection into format strings.
(bad copy/paste)
Uh oh!
There was an error while loading. Please reload this page.
| }) |unit| { | ||
| if (ns >= unit.ns) { | ||
| const units = @intToFloat(f64, ns_remaining) / @intToFloat(f64, unit.ns); | ||
| return format(writer, "{d}{}", .{ units, unit.sep }); |
There was a problem hiding this comment.
d will print the fp value with full precision, is that wanted?
Also, {s} for string formats please.
There was a problem hiding this comment.
It's probably reasonable to limit the max precision to 3 decimal places (i.e. down to the next unit). I don't think there's any way to do max precision with fmt, but I can div(floor(mul))
There was a problem hiding this comment.
Unfortunately @as(f64, 1) formatted with {d:.3} comes out as 1.000, where I would prefer to omit unnecessary precision
There was a problem hiding this comment.
Is using floats here really necessary? Since ns_remaining is a fixed-point number, you can manually split it into integral and fractional parts, and print them with formatInt.
There was a problem hiding this comment.
Is eliminating the floating point operation worth the extra complexity?
-// Floor to 3 decimal placesconstkunits=ns*1000/unit.ns;
-constunits=@intToFloat(f64, kunits) /1000.0;
-tryformatFloatDecimal(units, .{}, writer);
+tryformatInt(kunits/1000, 10, false, .{}, writer);
+// Write up to 3 decimal places+constfrac=kunits%1000;
+if (frac>0) {
+trywriter.writeByte('.');
+if (frac%10>0) {
+tryformatInt(frac, 10, false, .{ .fill='0', .width=3 }, writer);
+ } elseif (frac%100>0) {
+tryformatInt(frac/10, 10, false, .{ .fill='0', .width=2 }, writer);
+ } else {
+tryformatInt(frac/100, 10, false, .{ .fill='0', .width=1 }, writer);
+ }
+ }Serious question, I don't often work in environments where one floating operation would be noticeable
There was a problem hiding this comment.
Not sure how performance compares, but another option:
constfrac=kunits%1000;
if (frac>0) {
trywriter.writeByte('.');
varfrac_buf: [3]u8=undefined;
_=formatIntBuf(&frac_buf, frac, 10, false, .{ .fill='0', .width=3 });
tryformatBuf(frac_buf[0..std.mem.indexOfScalar(u8, &frac_buf, '0') orelsefrac_buf.len], .{}, writer);
}There was a problem hiding this comment.
Thank you for the feedback! I have eliminated the floating point operations.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
jdknezek
commented
Dec 4, 2020
I've addressed the first pass of comments - thanks for the feedback! |
jdknezek
commented
Dec 5, 2020
I've now eliminated the floating point operations. |
andrewrk
commented
Jan 12, 2021
`formatDuration` works on a writer, and `duration` wraps a u64 to allow pleasant injection into format strings.
formatDurationworks on a writer, anddurationwraps a u64 to allow pleasant injection into format strings.