Luna/libluna/src/Units.cpp

45 lines
1.3 KiB
C++
Raw Normal View History

#include <luna/Alloc.h>
#include <luna/CType.h>
2022-12-07 10:40:02 +00:00
#include <luna/Result.h>
#include <luna/ScopeGuard.h>
2022-12-07 11:25:42 +00:00
#include <luna/Units.h>
2022-11-30 11:42:11 +00:00
Result<String> to_dynamic_unit(usize value, usize round_after, bool separate, Unit unit, bool display_unit)
2022-11-30 11:42:11 +00:00
{
const usize multiplier = (usize)unit;
if (value < multiplier) { return String::format("%zu%s"_sv, value, display_unit ? " bytes" : ""); }
bool si = unit == Unit::SI;
2022-11-30 11:42:11 +00:00
const char* unit_prefixes = "KMGTPE";
if (si) unit_prefixes = "kMGTPE";
while (value > (multiplier * multiplier))
2022-11-30 11:42:11 +00:00
{
value /= multiplier;
2022-11-30 11:42:11 +00:00
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") : "");
2023-01-02 12:07:29 +00:00
}