diff --git a/src/misc/engnotation.c b/src/misc/engnotation.c index 78fdb5b01..6a029fc85 100644 --- a/src/misc/engnotation.c +++ b/src/misc/engnotation.c @@ -13,59 +13,74 @@ /* Print a floating-point number in engineering notation. Return string needs to be freed by the caller after its use. - numeric selects e3, e6, e9 etc. or k, M, G etc. */ -char *eng(double value, int digits, int numeric) + numeric selects e3, e6, e9 etc. or k, M, G etc. + If flag bytes is set true, numeric is overwritten, bytes + in multiples of 1024 are issued using k, M, G, T, P. */ +char *eng(double value, int digits, bool numeric, bool bytes) { - static char *prefix[] = { - "y", "z", "a", "f", "p", "n", "u", "m", "", - "k", "M", "G", "T", "P", "E", "Z", "Y" - }; + static char *prefix[] = { + "y", "z", "a", "f", "p", "n", "u", "m", "", + "k", "M", "G", "T", "P", "E", "Z", "Y" +}; #define PREFIX_END (PREFIX_START+\ -(int)((sizeof(prefix)/sizeof(char *)-1)*3)) - - double display, fract; - int expof10; - char *result, *sign; - - if(value < 0.0) { - sign = "-"; - value = -value; - } else { - sign = ""; - } - - // correctly round to desired precision - expof10 = lrint( floor( log10(value) ) ); - value *= pow(10.0, digits - 1 - expof10); - - fract = modf(value, &display); - if(fract >= 0.5) display += 1.0; - - value = display * pow(10.0, expof10 - digits + 1); + (int)((sizeof(prefix)/sizeof(char *)-1)*3)) - if(expof10 > 0) - expof10 = (expof10/3)*3; - else - expof10 = ((-expof10+3)/3)*(-3); + double display, fract; + int expof10; + char *result, *sign; - value *= pow(10.0, -expof10); - if (value >= 1000.0) { - value /= 1000.0; - expof10 += 3; - } - else if(value >= 100.0) - digits -= 2; - else if(value >= 10.0) - digits -= 1; + if (bytes) { + int i = 0; - if(numeric || (expof10 < PREFIX_START) || (expof10 > PREFIX_END)) - if (expof10 == 0) - result = tprintf("%s%.*f", sign, digits-1, value); - else - result = tprintf("%s%.*fe%d", sign, digits-1, value, expof10); - else - result = tprintf("%s%.*f %s", sign, digits-1, value, prefix[(expof10-PREFIX_START)/3]); + // Divide by 1024 until the unit is reached + while (value >= 1024. && i < 5) { + value /= 1024.; + i++; + } + result = tprintf("%.*g %s", digits - 1, value, prefix[i + 8]); + return result; + } - return result; + if(value < 0.0) { + sign = "-"; + value = -value; + } else { + sign = ""; + } + + // correctly round to desired precision + expof10 = lrint( floor( log10(value) ) ); + value *= pow(10.0, digits - 1 - expof10); + + fract = modf(value, &display); + if(fract >= 0.5) display += 1.0; + + value = display * pow(10.0, expof10 - digits + 1); + + + if(expof10 > 0) + expof10 = (expof10/3)*3; + else + expof10 = ((-expof10+3)/3)*(-3); + + value *= pow(10.0, -expof10); + if (value >= 1000.0) { + value /= 1000.0; + expof10 += 3; + } + else if(value >= 100.0) + digits -= 2; + else if(value >= 10.0) + digits -= 1; + + if(numeric || (expof10 < PREFIX_START) || (expof10 > PREFIX_END)) + if (expof10 == 0) + result = tprintf("%s%.*f", sign, digits-1, value); + else + result = tprintf("%s%.*fe%d", sign, digits-1, value, expof10); + else + result = tprintf("%s%.*f %s", sign, digits-1, value, prefix[(expof10-PREFIX_START)/3]); + + return result; }