This function trims unnecessary trailing zeros from a printed floating-point
number. It was written to be extremely general, however it is only ever used to
trim a number printed with the format string "%.02f". We can take advantage of
this fact to know that, if it can locate a period, there are exactly two digits
following this that need to be checked. This then allows implementing the
remainder of the function not as a loop but as simply a few branches.
Using tests/regression_tests/large/long_chain, which has been used for other
profiling in this area, this drops total executed instructions from
8160952787
to
8143275099, a speed up of ~2%.
#include "config.h"
+#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
/* gv_trim_zeros
* Trailing zeros are removed and decimal point, if possible.
+* Assumes the input is the result of %.02f printing.
*/
static void gv_trim_zeros(char* buf)
{
- char* dotp;
- char* p;
-
- if ((dotp = strchr(buf, '.'))) {
- p = dotp + 1;
- while (*p) p++; // find end of string
- p--;
- while (*p == '0') *p-- = '\0';
- if (*p == '.') // If all decimals were zeros, remove ".".
- *p = '\0';
- else
- p++;
+ char *dotp = strchr(buf, '.');
+ if (dotp == NULL) {
+ return;
+ }
+
+ // check this really is the result of %.02f printing
+ assert(isdigit(dotp[1]) && isdigit(dotp[2]) && dotp[3] == '\0');
+
+ if (dotp[2] == '0') {
+ if (dotp[1] == '0') {
+ *dotp = '\0';
+ } else {
+ dotp[2] = '\0';
}
+ }
}
void gvprintdouble(GVJ_t * job, double num)