mirror of
https://github.com/zeek/zeek.git
synced 2025-10-14 04:28:20 +00:00
GH-1450: Improve printing/logging of large double/interval/time values
The modp_dtoa/modp_dtoa2 functions aren't capable of handling double values larger than INT_MAX and fallback on using sprintf() in that situation. Previously, the format string to that sprintf() was "%e", defaulting to a precision of 6, which is already too few digits to represent a number known to be larger than INT_MAX. Now, an sprintf() is still performed for values larger than INT_MAX and still uses a scientific notation format, but in a way that uses as many decimal digits as needed to preserve information.
This commit is contained in:
parent
ea8367713b
commit
cc15c985ca
7 changed files with 88 additions and 19 deletions
|
@ -7,6 +7,7 @@
|
|||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
|
||||
// other interesting references on num to string convesion
|
||||
// http://www.jb.man.ac.uk/~slowe/cpp/itoa.html
|
||||
|
@ -30,6 +31,68 @@ static void strreverse(char* begin, char* end)
|
|||
aux = *end, *end-- = *begin, *begin++ = aux;
|
||||
}
|
||||
|
||||
// Expects 'str' to have been made using "%e" scientific notation format string
|
||||
static void sn_strip_trailing_zeros(char* str)
|
||||
{
|
||||
char* frac = 0;
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
if ( *str == '.' )
|
||||
{
|
||||
frac = str + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( *str == 0 )
|
||||
break;
|
||||
|
||||
++str;
|
||||
}
|
||||
|
||||
if ( ! frac )
|
||||
return;
|
||||
|
||||
char* exp = 0;
|
||||
char* trailing_zeros = 0;
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
if ( *frac == 0 )
|
||||
break;
|
||||
|
||||
if ( *frac == 'e' )
|
||||
{
|
||||
exp = frac;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( *frac == '0' )
|
||||
{
|
||||
if ( ! trailing_zeros )
|
||||
trailing_zeros = frac;
|
||||
}
|
||||
else
|
||||
trailing_zeros = 0;
|
||||
|
||||
++frac;
|
||||
}
|
||||
|
||||
if ( trailing_zeros && exp )
|
||||
{
|
||||
for ( ; ; )
|
||||
{
|
||||
*trailing_zeros = *exp;
|
||||
|
||||
if ( *exp == 0 )
|
||||
break;
|
||||
|
||||
++trailing_zeros;
|
||||
++exp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void modp_itoa10(int32_t value, char* str)
|
||||
{
|
||||
char* wstr=str;
|
||||
|
@ -108,7 +171,8 @@ void modp_dtoa(double value, char* str, int prec)
|
|||
which can be 100s of characters overflowing your buffers == bad
|
||||
*/
|
||||
if (value >= thres_max) {
|
||||
sprintf(str, "%e", neg ? -value : value);
|
||||
sprintf(str, "%.*e", DBL_DECIMAL_DIG - 1, neg ? -value : value);
|
||||
sn_strip_trailing_zeros(str);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -207,7 +271,8 @@ void modp_dtoa2(double value, char* str, int prec)
|
|||
which can be 100s of characters overflowing your buffers == bad
|
||||
*/
|
||||
if (value >= thres_max) {
|
||||
sprintf(str, "%e", neg ? -value : value);
|
||||
sprintf(str, "%.*e", DBL_DECIMAL_DIG - 1, neg ? -value : value);
|
||||
sn_strip_trailing_zeros(str);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue