commit fb11e6913f9da9ae350befa6deb560c10ac0afcd Author: Allison Vacanti 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 #include #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--;