diff options
author | Jens Axboe <jaxboe@fusionio.com> | 2010-09-16 09:35:34 +0200 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-09-16 09:35:34 +0200 |
commit | 1ec3d69b0ed8cc7a3eba0192685034d5442989e4 (patch) | |
tree | 425aad02e97c4965b2f0559e537687624e0cd0d3 /lib/num2str.c | |
parent | bd4d7e1ecd2388b89254148209ac2b172def8ebf (diff) | |
download | fio-1ec3d69b0ed8cc7a3eba0192685034d5442989e4.tar.gz fio-1ec3d69b0ed8cc7a3eba0192685034d5442989e4.tar.bz2 |
Implement a better num2str()
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'lib/num2str.c')
-rw-r--r-- | lib/num2str.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/lib/num2str.c b/lib/num2str.c new file mode 100644 index 00000000..e114cdf8 --- /dev/null +++ b/lib/num2str.c @@ -0,0 +1,48 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +/* + * Cheesy number->string conversion, complete with carry rounding error. + */ +char *num2str(unsigned long num, int maxlen, int base, int pow2) +{ + char postfix[] = { ' ', 'K', 'M', 'G', 'P', 'E' }; + unsigned int thousand[] = { 1000, 1024 }; + unsigned int modulo, decimals; + int post_index; + char tmp[32], fmt[8]; + char *buf; + + buf = malloc(128); + + for (post_index = 0; base > 1; post_index++) + base /= thousand[!!pow2]; + + modulo = -1U; + while (post_index < sizeof(postfix)) { + sprintf(tmp, "%lu", num); + if (strlen(tmp) <= maxlen) + break; + + modulo = num % thousand[!!pow2]; + num /= thousand[!!pow2]; + post_index++; + } + + if (modulo == -1U) { +done: + sprintf(buf, "%lu%c", num, postfix[post_index]); + return buf; + } + + sprintf(tmp, "%lu", num); + decimals = maxlen - strlen(tmp); + if (decimals <= 1) + goto done; + + sprintf(fmt, "%%.%uu", decimals - 1); + sprintf(tmp, fmt, modulo); + sprintf(buf, "%lu.%s%c", num, tmp, postfix[post_index]); + return buf; +} |