;/* gcc -Wall -o largefmt largefmt.c quit */ /* ** Formatting 64bit numbers with prefix ** ** Written by Harry "Piru" Sintonen ** Public Domain. ** */ #define FMT_LITTLE_ENDIAN 0 #define FMT_BIG_ENDIAN 1 /* Set according to CPU byteorder */ #define FMT_BYTE_ORDER FMT_BIG_ENDIAN /* 32bit unsigned integer */ typedef unsigned int fmt32_t; #define HAVE_SNPRINTF #include #include int largefmt(unsigned char *buf, size_t len, void *nump); #if FMT_BYTE_ORDER == FMT_LITTLE_ENDIAN #define MK64(a,b) {b,a} #else #define MK64(a,b) {a,b} #endif int main(void) { fmt32_t large[2] = MK64(0x1234567,0x89abcdef); //fmt32_t large[2] = MK64(0x1000000,0x89abcdef); //fmt32_t large[2] = MK64(0xffffffff,0xffffffff); //fmt32_t large[2] = MK64(0x126,0xffffffff); //fmt32_t large[2] = MK64(0,0xffff); //fmt32_t large[2] = MK64(0,0xfffffff); //fmt32_t large[2] = MK64(0,0x3fffffff); //fmt32_t large[2] = MK64(0,0x40000000); //fmt32_t large[2] = MK64(0,1126); unsigned char buf[10]; largefmt(buf, sizeof(buf), &large); printf("%s\n", buf); return 0; } #if FMT_BYTE_ORDER == FMT_LITTLE_ENDIAN # define FMT_LSLI 1 # define FMT_MSLI 0 #else # define FMT_LSLI 0 # define FMT_MSLI 1 #endif int largefmt(unsigned char *buf, size_t len, void *nump) { fmt32_t *p = nump; fmt32_t val, v, d; unsigned char prefix; #ifndef HAVE_SNPRINTF unsigned char tbuf[10]; /* 16383.9PB */ #endif /* determine magnitude, and shift accordingly */ if (p[FMT_LSLI] >= 1024 * 1024 >> 2) { prefix = 'P'; val = p[FMT_LSLI] >> (10 - 2); } else if (p[FMT_LSLI] >= 1024 >> 2) { prefix = 'T'; val = (p[FMT_LSLI] << (32 - 30)) | (p[FMT_MSLI] >> 30); } else if (p[FMT_MSLI] >= 1024 * 1024 * 1024) { prefix = 'G'; val = (p[FMT_LSLI] << (32 - 20)) | (p[FMT_MSLI] >> 20); } else if (p[FMT_MSLI] >= 1024 * 1024) { prefix = 'M'; val = p[FMT_MSLI] >> 10; } else if (p[FMT_MSLI] >= 1024) { prefix = 'K'; val = p[FMT_MSLI]; } else { #ifdef HAVE_SNPRINTF return snprintf(buf, len, "%uB", p[FMT_MSLI]); #else sprintf(tbuf, "%uB", p[FMT_MSLI]); strncpy(buf, tbuf, len); return (int) strlen(tbuf); /* really tbuf! */ #endif } v = val >> 10; d = val * 10 >> 10; if (d % 10 == 0 && d > v * 10) { v++; } #ifdef HAVE_SNPRINTF return snprintf(buf, len, "%u.%u%cB", v, d % 10, prefix); #else sprintf(tbuf, "%u.%u%cB", v, d % 10, prefix); strncpy(buf, tbuf, len); return (int) strlen(tbuf); /* really tbuf! */ #endif }