diff options
author | antirez <antirez@gmail.com> | 2014-12-02 18:19:30 +0100 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2014-12-03 10:41:06 +0100 |
commit | 42695fdfe670e82cd34125de405610e56c318493 (patch) | |
tree | 2449ef967a139b1c8c9a97ab06c74a925b753347 | |
parent | 164ad2ead133e23ccaeb74f42dc4e26a27a5c159 (diff) | |
download | redis-42695fdfe670e82cd34125de405610e56c318493.tar.gz |
Use exp format and more precision output for ZSCAN.
Ref: issue #2175
-rw-r--r-- | src/db.c | 2 | ||||
-rw-r--r-- | src/object.c | 28 | ||||
-rw-r--r-- | src/redis.h | 2 | ||||
-rw-r--r-- | src/t_hash.c | 2 | ||||
-rw-r--r-- | src/t_string.c | 2 |
5 files changed, 21 insertions, 15 deletions
@@ -371,7 +371,7 @@ void scanCallback(void *privdata, const dictEntry *de) { } else if (o->type == REDIS_ZSET) { key = dictGetKey(de); incrRefCount(key); - val = createStringObjectFromLongDouble(*(double*)dictGetVal(de)); + val = createStringObjectFromLongDouble(*(double*)dictGetVal(de),0); } else { redisPanic("Type not handled in SCAN callback."); } diff --git a/src/object.c b/src/object.c index 56528690f..d0916d395 100644 --- a/src/object.c +++ b/src/object.c @@ -69,9 +69,11 @@ robj *createStringObjectFromLongLong(long long value) { return o; } -/* Note: this function is defined into object.c since here it is where it - * belongs but it is actually designed to be used just for INCRBYFLOAT */ -robj *createStringObjectFromLongDouble(long double 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. */ +robj *createStringObjectFromLongDouble(long double value, int humanfriendly) { char buf[256]; int len; @@ -80,15 +82,19 @@ robj *createStringObjectFromLongDouble(long double value) { * 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) { - char *p = buf+len-1; - while(*p == '0') { - p--; - len--; + if (humanfriendly) { + len = snprintf(buf,sizeof(buf),"%.17Lf", value); + /* Now remove trailing zeroes after the '.' */ + if (strchr(buf,'.') != NULL) { + char *p = buf+len-1; + while(*p == '0') { + p--; + len--; + } + if (*p == '.') len--; } - if (*p == '.') len--; + } else { + len = snprintf(buf,sizeof(buf),"%.17Lg", value); } return createStringObject(buf,len); } diff --git a/src/redis.h b/src/redis.h index 04b8a1a4e..a7a3c7ec5 100644 --- a/src/redis.h +++ b/src/redis.h @@ -1037,7 +1037,7 @@ robj *tryObjectEncoding(robj *o); robj *getDecodedObject(robj *o); size_t stringObjectLen(robj *o); robj *createStringObjectFromLongLong(long long value); -robj *createStringObjectFromLongDouble(long double value); +robj *createStringObjectFromLongDouble(long double value, int humanfriendly); robj *createListObject(void); robj *createZiplistObject(void); robj *createSetObject(void); diff --git a/src/t_hash.c b/src/t_hash.c index 6bec70686..fff3bf9a4 100644 --- a/src/t_hash.c +++ b/src/t_hash.c @@ -568,7 +568,7 @@ void hincrbyfloatCommand(redisClient *c) { } value += incr; - new = createStringObjectFromLongDouble(value); + new = createStringObjectFromLongDouble(value,1); hashTypeTryObjectEncoding(o,&c->argv[2],NULL); hashTypeSet(o,c->argv[2],new); addReplyBulk(c,new); diff --git a/src/t_string.c b/src/t_string.c index f06693815..96c978add 100644 --- a/src/t_string.c +++ b/src/t_string.c @@ -387,7 +387,7 @@ void incrbyfloatCommand(redisClient *c) { addReplyError(c,"increment would produce NaN or Infinity"); return; } - new = createStringObjectFromLongDouble(value); + new = createStringObjectFromLongDouble(value,1); if (o) dbOverwrite(c->db,c->argv[1],new); else |