aboutsummaryrefslogtreecommitdiffstats
path: root/src/util.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2010-05-27 18:59:02 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2010-05-27 18:59:02 +0400
commit0dc48ea239965d05b760cb9d8e570e0d91aedb77 (patch)
treedb2d4c9b80a3408d12cb8bf4cfad57d45238abb9 /src/util.c
parentac8249b6ee746f022b0753789e6e2b46ab842abc (diff)
downloadrspamd-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.c78
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;