Использование табличного представления, расширенного до EiB.
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DIM(x) (sizeof(x)/sizeof(*(x)))
static const char *sizes[] = { "EiB", "PiB", "TiB", "GiB", "MiB", "KiB", "B" };
static const uint64_t exbibytes = 1024ULL * 1024ULL * 1024ULL *
1024ULL * 1024ULL * 1024ULL;
char *
calculateSize(uint64_t size)
{
char *result = (char *) malloc(sizeof(char) * 20);
uint64_t multiplier = exbibytes;
int i;
for (i = 0; i < DIM(sizes); i++, multiplier /= 1024)
{
if (size < multiplier)
continue;
if (size % multiplier == 0)
sprintf(result, "%" PRIu64 " %s", size / multiplier, sizes[i]);
else
sprintf(result, "%.1f %s", (float) size / multiplier, sizes[i]);
return result;
}
strcpy(result, "0");
return result;
}
Тестовый код
int main(void)
{
uint64_t list[] =
{
0, 1, 2, 34, 900, 1023, 1024, 1025, 2048, 1024 * 1024,
1024 * 1024 * 1024 + 1024 * 1024 * 400
};
int i;
for (i = 0; i < DIM(list); i++)
{
char *str = calculateSize(list[i]);
printf("%18" PRIu64 " = %s\n", list[i], str);
free(str);
}
return 0;
}
Тестовый вывод
0 = 0
1 = 1 B
2 = 2 B
34 = 34 B
900 = 900 B
1023 = 1023 B
1024 = 1 KiB
1025 = 1.0 KiB
2048 = 2 KiB
1048576 = 1 MiB
1493172224 = 1.4 GiB