mirror of
https://github.com/bkaradzic/bx.git
synced 2026-02-17 12:42:34 +01:00
Added: bx::formatHumanNumber. (#368)
This commit is contained in:
committed by
GitHub
parent
016167548e
commit
36ad6131f4
@@ -450,6 +450,16 @@ namespace bx
|
|||||||
template <typename Ty>
|
template <typename Ty>
|
||||||
void stringPrintf(Ty& _out, const char* _format, ...);
|
void stringPrintf(Ty& _out, const char* _format, ...);
|
||||||
|
|
||||||
|
/// Format number to human readable representation.
|
||||||
|
///
|
||||||
|
/// @param[out] _out Output string.
|
||||||
|
/// @param[in] _count Maximum output string count.
|
||||||
|
/// @param[in] _value Value.
|
||||||
|
/// @param[in] _numFrac Number of fraction digits.
|
||||||
|
/// @returns Length of output string.
|
||||||
|
///
|
||||||
|
int32_t formatHumanNumber(char* _out, int32_t _count, double _value, int32_t _numFrac);
|
||||||
|
|
||||||
/// Convert size in bytes to human readable string kibi units.
|
/// Convert size in bytes to human readable string kibi units.
|
||||||
int32_t prettify(char* _out, int32_t _count, uint64_t _value, Units::Enum _units = Units::Kibi);
|
int32_t prettify(char* _out, int32_t _count, uint64_t _value, Units::Enum _units = Units::Kibi);
|
||||||
|
|
||||||
|
|||||||
@@ -1280,6 +1280,70 @@ namespace bx
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t formatHumanNumber(char* _out, int32_t _count, double _value, int32_t _numFrac)
|
||||||
|
{
|
||||||
|
char temp[64];
|
||||||
|
int32_t len = snprintf(temp, sizeof(temp), "%.*f", _numFrac, _value);
|
||||||
|
int32_t intPartLen = len;
|
||||||
|
|
||||||
|
if (len >= _numFrac+1
|
||||||
|
&& '.' == temp[len-_numFrac-1])
|
||||||
|
{
|
||||||
|
intPartLen = len-_numFrac-1;
|
||||||
|
|
||||||
|
bool zero = true;
|
||||||
|
|
||||||
|
for (int32_t ii = _numFrac; 0 < ii && zero; --ii)
|
||||||
|
{
|
||||||
|
zero &= temp[len-ii] == '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zero)
|
||||||
|
{
|
||||||
|
temp[len-_numFrac-1] = '\0';
|
||||||
|
len = intPartLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int32_t fracPartLen = len - intPartLen;
|
||||||
|
const int32_t commas = (intPartLen > 3) ? (intPartLen - 1) / 3 : 0;
|
||||||
|
const int32_t total = intPartLen + fracPartLen + commas;
|
||||||
|
|
||||||
|
if (_count < total)
|
||||||
|
{
|
||||||
|
if (0 < _count)
|
||||||
|
{
|
||||||
|
_out[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* out = _out + total;
|
||||||
|
*out = '\0';
|
||||||
|
|
||||||
|
if (0 != fracPartLen)
|
||||||
|
{
|
||||||
|
out -= fracPartLen;
|
||||||
|
memCopy(out, &temp[intPartLen], fracPartLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t group = 0;
|
||||||
|
for (int32_t ii = intPartLen - 1; ii >= 0; --ii)
|
||||||
|
{
|
||||||
|
*--out = temp[ii];
|
||||||
|
|
||||||
|
if (3 == ++group
|
||||||
|
&& 0 < ii)
|
||||||
|
{
|
||||||
|
*--out = ',';
|
||||||
|
group = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
static const char s_units[] = { 'B', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' };
|
static const char s_units[] = { 'B', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' };
|
||||||
|
|
||||||
template<uint32_t Kilo, char KiloCh0, char KiloCh1, CharFn fn>
|
template<uint32_t Kilo, char KiloCh0, char KiloCh1, CharFn fn>
|
||||||
@@ -1295,7 +1359,10 @@ namespace bx
|
|||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
return snprintf(_out, _count, "%0.2f %c%c%c", value
|
char human[32];
|
||||||
|
formatHumanNumber(human, sizeof(human), value, 2);
|
||||||
|
|
||||||
|
return snprintf(_out, _count, "%s %c%c%c", human
|
||||||
, fn(s_units[idx])
|
, fn(s_units[idx])
|
||||||
, idx > 0 ? KiloCh0 : '\0'
|
, idx > 0 ? KiloCh0 : '\0'
|
||||||
, KiloCh1
|
, KiloCh1
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ TEST_CASE("prettify", "[string]")
|
|||||||
{
|
{
|
||||||
char tmp[1024];
|
char tmp[1024];
|
||||||
prettify(tmp, BX_COUNTOF(tmp), 4000, bx::Units::Kilo);
|
prettify(tmp, BX_COUNTOF(tmp), 4000, bx::Units::Kilo);
|
||||||
REQUIRE(0 == bx::strCmp(tmp, "4.00 kB") );
|
REQUIRE(0 == bx::strCmp(tmp, "4 kB") );
|
||||||
|
|
||||||
prettify(tmp, BX_COUNTOF(tmp), 4096, bx::Units::Kibi);
|
prettify(tmp, BX_COUNTOF(tmp), 4096, bx::Units::Kibi);
|
||||||
REQUIRE(0 == bx::strCmp(tmp, "4.00 KiB") );
|
REQUIRE(0 == bx::strCmp(tmp, "4 KiB") );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("chars", "[string]")
|
TEST_CASE("chars", "[string]")
|
||||||
@@ -762,3 +762,37 @@ TEST(tinystl_string_assign)
|
|||||||
CHECK( other.size() == 0 );
|
CHECK( other.size() == 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool testFormatHumanNumber(bx::StringView _expected, double _value, int32_t _numFrac, int32_t _bufferSize = 32)
|
||||||
|
{
|
||||||
|
char* tmp = (char*)BX_STACK_ALLOC(_bufferSize);
|
||||||
|
int32_t total = bx::formatHumanNumber(tmp, _bufferSize, _value, _numFrac);
|
||||||
|
|
||||||
|
bx::StringView human(tmp, total);
|
||||||
|
|
||||||
|
const bool result = 0 == bx::strCmp(human, _expected);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
DBG(
|
||||||
|
"expected: '%S' (len: %d), human: '%S' (len: %d)"
|
||||||
|
, &_expected
|
||||||
|
, _expected.getLength()
|
||||||
|
, &human
|
||||||
|
, human.getLength()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("formatHumanNumber", "[string]")
|
||||||
|
{
|
||||||
|
REQUIRE(testFormatHumanNumber("1,389,983,113.89", 1389983113.891389, 2) );
|
||||||
|
REQUIRE(testFormatHumanNumber("13,899,831.1389", 13899831.1389, 4) );
|
||||||
|
REQUIRE(testFormatHumanNumber("1,389.10", 1389.1, 2) );
|
||||||
|
REQUIRE(testFormatHumanNumber("1,389", 1389.0, 8) );
|
||||||
|
REQUIRE(testFormatHumanNumber("0", 0.0, 2) );
|
||||||
|
|
||||||
|
REQUIRE(testFormatHumanNumber("", 1389983113.891389, 2, 4) );
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user