| 1 | const std = @import("std"); |
| 2 | const string = []const u8; |
| 3 | const extras = @import("./lib.zig"); |
| 4 | |
| 5 | pub fn reduceNumber(writer: anytype, input: u64, comptime unit: u64, comptime base: string, comptime prefixes: string) !void { |
| 6 | if (input < unit) { |
| 7 | return try writer.print("{d} {s}", .{ input, base }); |
| 8 | } |
| 9 | var div = unit; |
| 10 | var exp: usize = 0; |
| 11 | var n = input / unit; |
| 12 | while (n >= unit) : (n /= unit) { |
| 13 | div *= unit; |
| 14 | exp += 1; |
| 15 | if (exp == prefixes.len - 1) break; |
| 16 | } |
| 17 | const input_f: f64 = @floatFromInt(input); |
| 18 | const div_f: f64 = @floatFromInt(div); |
| 19 | return try writer.print("{d:.3} {s}{s}", .{ input_f / div_f, prefixes[exp..][0..1], base }); |
| 20 | } |
| 21 | |
| 22 | test { |
| 23 | const allocator = std.testing.allocator; |
| 24 | var list = std.Io.Writer.Allocating.init(allocator); |
| 25 | defer list.deinit(); |
| 26 | try reduceNumber(&list.writer, 1, 60, "s", "mh"); |
| 27 | try std.testing.expect(std.mem.eql(u8, list.written(), "1 s")); |
| 28 | } |
| 29 | test { |
| 30 | const allocator = std.testing.allocator; |
| 31 | var list = std.Io.Writer.Allocating.init(allocator); |
| 32 | defer list.deinit(); |
| 33 | try reduceNumber(&list.writer, 60, 60, "s", "mh"); |
| 34 | try std.testing.expect(std.mem.eql(u8, list.written(), "1.000 ms")); |
| 35 | } |
| 36 | test { |
| 37 | const allocator = std.testing.allocator; |
| 38 | var list = std.Io.Writer.Allocating.init(allocator); |
| 39 | defer list.deinit(); |
| 40 | try reduceNumber(&list.writer, 3600, 60, "s", "mh"); |
| 41 | try std.testing.expect(std.mem.eql(u8, list.written(), "1.000 hs")); |
| 42 | } |
| 43 | test { |
| 44 | const allocator = std.testing.allocator; |
| 45 | var list = std.Io.Writer.Allocating.init(allocator); |
| 46 | defer list.deinit(); |
| 47 | try reduceNumber(&list.writer, 216000, 60, "s", "mh"); |
| 48 | try std.testing.expect(std.mem.eql(u8, list.written(), "60.000 hs")); |
| 49 | } |