diff options
author | antirez <antirez@gmail.com> | 2014-12-03 10:33:00 +0100 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2014-12-03 10:41:06 +0100 |
commit | 6e0277769d68e4f73c24c9aea8755627a415518f (patch) | |
tree | f3a659cbc9b18393670e0c8a6d3d898d91bf634c | |
parent | 42695fdfe670e82cd34125de405610e56c318493 (diff) | |
download | redis-6e0277769d68e4f73c24c9aea8755627a415518f.tar.gz |
Handle infinite explicitly in createStringObjectFromLongLong().
-rw-r--r-- | src/object.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/src/object.c b/src/object.c index d0916d395..cd774cb84 100644 --- a/src/object.c +++ b/src/object.c @@ -71,18 +71,30 @@ robj *createStringObjectFromLongLong(long long value) { /* Create a string object from a long double. If humanfriendly is non-zero * it does not use exponential format and trims trailing zeroes at the end, - * however this result in loss of precision. Otherwise exp format is used - * and the output of snprintf() is not modified. */ + * however this results in loss of precision. Otherwise exp format is used + * and the output of snprintf() is not modified. + * + * The 'humanfriendly' option is used for INCRBYFLOAT and HINCRBYFLOAT. */ robj *createStringObjectFromLongDouble(long double value, int humanfriendly) { char buf[256]; int len; - /* We use 17 digits precision since with 128 bit floats that precision - * after rounding is able to represent most small decimal numbers in a way - * that is "non surprising" for the user (that is, most small decimal - * numbers will be represented in a way that when converted back into - * a string are exactly the same as what the user typed.) */ - if (humanfriendly) { + if (isinf(value)) { + /* Libc in odd systems (Hi Solaris!) will format infinite in a + * different way, so better to handle it in an explicit way. */ + if (value > 0) { + memcpy(buf,"inf",3); + len = 3; + } else { + memcpy(buf,"-inf",4); + len = 4; + } + } else if (humanfriendly) { + /* We use 17 digits precision since with 128 bit floats that precision + * after rounding is able to represent most small decimal numbers in a + * way that is "non surprising" for the user (that is, most small + * decimal numbers will be represented in a way that when converted + * back into a string are exactly the same as what the user typed.) */ len = snprintf(buf,sizeof(buf),"%.17Lf", value); /* Now remove trailing zeroes after the '.' */ if (strchr(buf,'.') != NULL) { |