1const std = @import("std");
2const string = []const u8;
3const extras = @import("./lib.zig");
4
5pub 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
22test {
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}
29test {
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}
36test {
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}
43test {
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}