#include #include #include #include #include Result to_dynamic_unit(usize value, usize round_after, bool separate, Unit unit, bool display_unit) { const usize multiplier = (usize)unit; if (value < multiplier) { return String::format("%zu%s"_sv, value, display_unit ? " bytes" : ""); } bool si = unit == Unit::SI; const char* unit_prefixes = "KMGTPE"; if (si) unit_prefixes = "kMGTPE"; while (value > (multiplier * multiplier)) { value /= multiplier; unit_prefixes++; } const usize divider = (si ? 100 : 103); usize fixed = value / multiplier; usize rest = (value % multiplier) / divider; bool round = fixed >= round_after; if (round) { if (value % multiplier) fixed++; return String::format("%zu%s%c%s"_sv, fixed, separate ? " " : "", *unit_prefixes, display_unit ? (si ? "B" : "iB") : ""); } if ((value % multiplier) % divider) rest++; if (rest > 9) { rest = 0; fixed++; } return String::format("%zu.%zu%s%c%s"_sv, fixed, rest, separate ? " " : "", *unit_prefixes, display_unit ? (si ? "B" : "iB") : ""); }