提交 b6b7bc0b 编写于 作者: A antirez

Use exp format and more precision output for ZSCAN.

Ref: issue #2175
上级 6a0b1b5b
......@@ -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.");
}
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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);
......
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册