summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2014-12-02 18:19:30 +0100
committerantirez <antirez@gmail.com>2014-12-02 18:20:09 +0100
commit92c5ab40295260352f0da09616ff15b499251bad (patch)
treea7991d0df9fde2a621730a20a0b3a7a48cdcaa7a
parent5bd3b9d93fe0747c71e86b601f936f4aae3664fb (diff)
downloadredis-92c5ab40295260352f0da09616ff15b499251bad.tar.gz
Use exp format and more precision output for ZSCAN.
Ref: issue #2175
-rw-r--r--src/db.c2
-rw-r--r--src/object.c28
-rw-r--r--src/redis.h2
-rw-r--r--src/t_hash.c2
-rw-r--r--src/t_string.c2
5 files changed, 21 insertions, 15 deletions
diff --git a/src/db.c b/src/db.c
index d5a381daf..2982c0166 100644
--- a/src/db.c
+++ b/src/db.c
@@ -381,7 +381,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 6b8e42477..2b2d463f6 100644
--- a/src/object.c
+++ b/src/object.c
@@ -109,9 +109,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;
@@ -120,15 +122,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 855ae5742..5b1b33a84 100644
--- a/src/redis.h
+++ b/src/redis.h
@@ -1116,7 +1116,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 f5ceb36e9..7f33bba0c 100644
--- a/src/t_hash.c
+++ b/src/t_hash.c
@@ -565,7 +565,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 74c05793c..e3c1e5f4a 100644
--- a/src/t_string.c
+++ b/src/t_string.c
@@ -397,7 +397,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