diff --git a/VERSION b/VERSION index e6e0138a..4e711c14 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.510 +8.3.511 diff --git a/ext2spice/ext2spice.c b/ext2spice/ext2spice.c index 6bc56752..c2f2bbdb 100644 --- a/ext2spice/ext2spice.c +++ b/ext2spice/ext2spice.c @@ -3123,6 +3123,85 @@ FILE *outf; } } +/* + * ---------------------------------------------------------------------------- + * + * nDecimals() --- + * + * Code taken from discussion at + * https://stackoverflow.com/questions/277772/avoid-trailing-zeroes-in-printf + * + * Modifies value "d" by truncating it to precision "n", writing the result + * into string "s". + * + * ---------------------------------------------------------------------------- + */ + +void +nDecimals(char *s, double d, int n) +{ + int sz; + double d2; + + // Allow for negative. + d2 = (d >= 0) ? d : -d; + sz = (d >= 0) ? 0 : 1; + + // Add one for each whole digit (0.xx special case). + if (d2 < 1) sz++; + while (d2 >= 1) + { + d2 /= 10.0; + sz++; + } + + // Adjust for decimal point and fractionals. + sz += 1 + n; + + // Create formatted string then use it. + sprintf(s, "%*.*f", sz, n, d); +} + +/* + * ---------------------------------------------------------------------------- + * + * morphNumericString() --- + * + * Code taken from discussion at + * https://stackoverflow.com/questions/277772/avoid-trailing-zeroes-in-printf + * + * Remove trailing zeros from the number represented in string "s". + * Assume a precision (defined as precision after the decimal point) of "n". + * + * ---------------------------------------------------------------------------- + */ + +void +morphNumericString(char *s, int n) +{ + char *p; + int count; + + p = strchr (s, '.'); // Find decimal point, if any. + if (p != NULL) + { + count = n; // Adjust for more or less decimals. + while (count >= 0) // Maximum decimals allowed. + { + count--; + if (*p == '\0') // If there's less than desired. + break; + p++; // Next character. + } + *p-- = '\0'; // Truncate string. + while (*p == '0') // Remove trailing zeros. + *p-- = '\0'; + + if (*p == '.') // If all decimals were zeros, remove ".". + *p = '\0'; + } +} + /* * ---------------------------------------------------------------------------- * @@ -3145,6 +3224,7 @@ esSIvalue(file, value) FILE *file; float value; { + char vstr[32]; char suffix = '\0'; int precision; float avalue; @@ -3195,27 +3275,16 @@ esSIvalue(file, value) /* Note that "%g" is preferred because it produces more readable * output. However, it changes the definition of the precision * from significant digits after the radix to total significant - * digits. Determine the proper precision to use by reading - * back the formatted value and comparing to the original value. + * digits. Using a solution provided in StackOverflow (see above). */ - for (precision = 3; precision < 9; precision++) - { - int vtrunc, ptrunc; - char ptest[32]; - float pvalue; - - sprintf(ptest, "%.*g", precision, value); - sscanf(ptest, "%f", &pvalue); - vtrunc = (int)(0.5 + (value * 1e6)); - ptrunc = (int)(0.5 + (pvalue * 1e6)); - if (vtrunc == ptrunc) break; - } + nDecimals(vstr, (double)value, 5); + morphNumericString(vstr, 5); if (suffix == '\0') - fprintf(file, "%.*g", precision, value); + fprintf(file, "%s", vstr); else - fprintf(file, "%.*g%c", precision, value, suffix); + fprintf(file, "%s%c", vstr, suffix); } /*