commit fb11e6913f9da9ae350befa6deb560c10ac0afcd
Author: Allison Vacanti <allison.vacanti@kitware.com>
Date: Thu Oct 4 13:12:01 2018 -0400
Improve small number writing in HPDF_FToA.
This was truncating all numbers at 1e-5, now it ensures that 5
significant figures will always be written for values > 1e-20.
diff --git a/include/hpdf_consts.h b/include/hpdf_consts.h
index 2dbf396..d874f7f 100644
--- a/include/hpdf_consts.h
+++ b/include/hpdf_consts.h
@@ -32,7 +32,7 @@
/* buffer size which is required when we convert to character string. */
#define HPDF_TMP_BUF_SIZ 512
#define HPDF_SHORT_BUF_SIZ 32
-#define HPDF_REAL_LEN 11
+#define HPDF_REAL_LEN 64
#define HPDF_INT_LEN 11
#define HPDF_TEXT_DEFAULT_LEN 256
#define HPDF_UNICODE_HEADER_LEN 2
diff --git a/include/hpdf_types.h b/include/hpdf_types.h
index a35fe8f..ce5cbd7 100644
--- a/include/hpdf_types.h
+++ b/include/hpdf_types.h
@@ -45,6 +45,12 @@ typedef signed int HPDF_INT;
typedef unsigned int HPDF_UINT;
+/* 64bit integer types
+ */
+typedef signed long long HPDF_INT64;
+typedef unsigned long long HPDF_UINT64;
+
+
/* 32bit integer types
*/
typedef signed int HPDF_INT32;
diff --git a/src/hpdf_utils.c b/src/hpdf_utils.c
index 728da5a..6e9a8b7 100644
--- a/src/hpdf_utils.c
+++ b/src/hpdf_utils.c
@@ -15,6 +15,7 @@
*
*/
+#include <math.h>
#include <stdlib.h>
#include "hpdf_utils.h"
#include "hpdf_consts.h"
@@ -188,6 +189,10 @@ HPDF_FToA (char *s,
char* sptr = s;
char* t;
HPDF_UINT32 i;
+ HPDF_UINT32 prec;
+ HPDF_INT32 logVal;
+ HPDF_REAL roundInc;
+ HPDF_INT64 fShift;
if (val > HPDF_LIMIT_MAX_REAL)
val = HPDF_LIMIT_MAX_REAL;
@@ -203,12 +208,24 @@ HPDF_FToA (char *s,
val = -val;
}
+ /* Compute the decimal precision to write at least 5 significant figures */
+ logVal = (HPDF_INT32)(val > 1e-20 ? log10(val) : 0.);
+ if (logVal >= 0) {
+ prec = 5;
+ }
+ else {
+ prec = -logVal + 5;
+ }
+
+ roundInc = 0.5 * (1. / pow((HPDF_REAL)10, (HPDF_REAL)prec));
+ fShift = (HPDF_INT64)pow((HPDF_REAL)10, (HPDF_REAL)prec);
+
/* separate an integer part and a decimal part. */
- int_val = (HPDF_INT32)(val + 0.000005);
- fpart_val = (HPDF_INT32)((HPDF_REAL)(val - int_val + 0.000005) * 100000);
+ int_val = (HPDF_INT64)(val + roundInc);
+ fpart_val = (HPDF_INT64)((HPDF_REAL)(val - int_val + roundInc) * fShift);
/* process decimal part */
- for (i = 0; i < 5; i++) {
+ for (i = 0; i < prec; i++) {
*t = (char)((char)(fpart_val % 10) + '0');
fpart_val /= 10;
t--;