diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-05-19 10:35:34 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-05-19 10:35:34 +0100 |
commit | 2dc49d136538276625a38d0944d221a1f0580d54 (patch) | |
tree | 4bb9a903ae4cdf86ff7c7244d58ae0f0ab97dafa /contrib/fpconv | |
parent | 31a1224de44218d8252f25aa42e2544b7ef74119 (diff) | |
download | rspamd-2dc49d136538276625a38d0944d221a1f0580d54.tar.gz rspamd-2dc49d136538276625a38d0944d221a1f0580d54.zip |
[Fix] Fix some more corner cases for fpconv
Diffstat (limited to 'contrib/fpconv')
-rw-r--r-- | contrib/fpconv/fpconv.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/contrib/fpconv/fpconv.c b/contrib/fpconv/fpconv.c index 4ec2e3560..3b96af270 100644 --- a/contrib/fpconv/fpconv.c +++ b/contrib/fpconv/fpconv.c @@ -236,26 +236,24 @@ static int emit_digits(char* digits, int ndigits, char* dest, int K, bool neg, return ndigits + 2 + offset; } else { - /* Overflow */ - dest[2] = '0'; - return 3; + goto scientific_fallback; } /* fp > 1.0 */ } else { - memcpy(dest, digits, offset); - /* Overflow check */ if (ndigits <= 23) { + memcpy(dest, digits, offset); dest[offset] = '.'; memcpy(dest + offset + 1, digits + offset, ndigits - offset); return ndigits + 1; } - return offset; + goto scientific_fallback; } } +scientific_fallback: /* write decimal w/ scientific notation */ ndigits = minv(ndigits, 18 - neg); @@ -296,9 +294,18 @@ static int emit_digits(char* digits, int ndigits, char* dest, int K, bool neg, static int filter_special(double fp, char* dest) { + int nchars = 3; + if(fp == 0.0) { - dest[0] = '0'; - return 1; + if(get_dbits(fp) & signmask) { + dest[0] = '-'; + dest[1] = '0'; + return 2; + } + else { + dest[0] = '0'; + return 1; + } } uint64_t bits = get_dbits(fp); @@ -311,12 +318,18 @@ static int filter_special(double fp, char* dest) if(bits & fracmask) { dest[0] = 'n'; dest[1] = 'a'; dest[2] = 'n'; - } else { - dest[0] = 'i'; dest[1] = 'n'; dest[2] = 'f'; + if(get_dbits(fp) & signmask) { + dest[0] = '-'; + dest[1] = 'i'; dest[2] = 'n'; dest[3] = 'f'; + nchars = 4; + } + else { + dest[0] = 'i'; dest[1] = 'n'; dest[2] = 'f'; + } } - return 3; + return nchars; } int fpconv_dtoa(double d, char dest[24], bool scientific) @@ -326,11 +339,6 @@ int fpconv_dtoa(double d, char dest[24], bool scientific) int str_len = 0; bool neg = false; - if(get_dbits(d) & signmask) { - dest[0] = '-'; - str_len++; - neg = true; - } int spec = filter_special(d, dest + str_len); @@ -338,6 +346,12 @@ int fpconv_dtoa(double d, char dest[24], bool scientific) return str_len + spec; } + if(get_dbits(d) & signmask) { + dest[0] = '-'; + str_len++; + neg = true; + } + int K = 0; int ndigits = grisu2(d, digits, &K); |