diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2010-05-27 18:59:02 +0400 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2010-05-27 18:59:02 +0400 |
commit | 0dc48ea239965d05b760cb9d8e570e0d91aedb77 (patch) | |
tree | db2d4c9b80a3408d12cb8bf4cfad57d45238abb9 /src/util.c | |
parent | ac8249b6ee746f022b0753789e6e2b46ab842abc (diff) | |
download | rspamd-0dc48ea239965d05b760cb9d8e570e0d91aedb77.tar.gz rspamd-0dc48ea239965d05b760cb9d8e570e0d91aedb77.zip |
* Convert statistic sums to use long double for counters
* Use hyperbolic tangent for internal normalizer
Diffstat (limited to 'src/util.c')
-rw-r--r-- | src/util.c | 78 |
1 files changed, 71 insertions, 7 deletions
diff --git a/src/util.c b/src/util.c index c093ccc36..bf0a491f3 100644 --- a/src/util.c +++ b/src/util.c @@ -1034,7 +1034,10 @@ get_statfile_by_symbol (statfile_pool_t *pool, struct classifier_config *ccf, * %[0][width|m][u][x|X]i int/ngx_int_t * %[0][width][u][x|X]D int32_t/uint32_t * %[0][width][u][x|X]L int64_t/uint64_t - * %[0][width][.width]f float + * %[0][width][.width]f double + * %[0][width][.width]F long double + * %[0][width][.width]g double + * %[0][width][.width]G long double * %P pid_t * %r rlim_t * %p void * @@ -1082,7 +1085,7 @@ rspamd_vsnprintf (u_char *buf, size_t max, const char *fmt, va_list args) { u_char *p, zero, *last; int d; - float f, scale; + long double f, scale; size_t len, slen; int64_t i64; uint64_t ui64; @@ -1144,7 +1147,6 @@ rspamd_vsnprintf (u_char *buf, size_t max, const char *fmt, va_list args) sign = 0; fmt++; continue; - case '.': fmt++; @@ -1258,7 +1260,43 @@ rspamd_vsnprintf (u_char *buf, size_t max, const char *fmt, va_list args) case 'f': - f = (float) va_arg (args, double); + f = (double) va_arg (args, double); + if (f < 0) { + *buf++ = '-'; + f = -f; + } + + ui64 = (int64_t) f; + + buf = rspamd_sprintf_num (buf, last, ui64, zero, 0, width); + + if (frac_width) { + + if (buf < last) { + *buf++ = '.'; + } + + scale = 1.0; + + for (i = 0; i < frac_width; i++) { + scale *= 10.0; + } + + /* + * (int64_t) cast is required for msvc6: + * it can not convert uint64_t to double + */ + ui64 = (uint64_t) ((f - (int64_t) ui64) * scale); + + buf = rspamd_sprintf_num (buf, last, ui64, '0', 0, frac_width); + } + + fmt++; + + continue; + + case 'F': + f = (long double) va_arg (args, long double); if (f < 0) { *buf++ = '-'; @@ -1282,9 +1320,9 @@ rspamd_vsnprintf (u_char *buf, size_t max, const char *fmt, va_list args) } /* - * (int64_t) cast is required for msvc6: - * it can not convert uint64_t to double - */ + * (int64_t) cast is required for msvc6: + * it can not convert uint64_t to double + */ ui64 = (uint64_t) ((f - (int64_t) ui64) * scale); buf = rspamd_sprintf_num (buf, last, ui64, '0', 0, frac_width); @@ -1294,6 +1332,32 @@ rspamd_vsnprintf (u_char *buf, size_t max, const char *fmt, va_list args) continue; + case 'g': + f = (long double) va_arg (args, double); + + if (f < 0) { + *buf++ = '-'; + f = -f; + } + g_ascii_formatd (buf, last - buf, "%g", (double)f); + buf += strlen (buf); + fmt++; + + continue; + + case 'G': + f = (long double) va_arg (args, long double); + + if (f < 0) { + *buf++ = '-'; + f = -f; + } + g_ascii_formatd (buf, last - buf, "%g", (double)f); + buf += strlen (buf); + fmt++; + + continue; + case 'p': ui64 = (uintptr_t) va_arg (args, void *); hex = 2; |