ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

REdis zset和double

2019-04-25 17:41:48  阅读:286  来源: 互联网

标签:127.0 zset 0.1 double REdis 6379 k1 m1


 

平台:x86_64

结论:Zset的最大分数不要超过18014398509481982(17位数字,54位二进制),否则不会得到期望的值。

REdis:5.0.4

 

Zset采用double存储分数值(score),而incrbyfloat和hincrbyfloat采用的是long double存储数值。

 

double本身是可以存储比18014398509481982(17位数字,54位二进制)大的值,比如18014398509481983(也是17位数字,54位二进制)。但REdis在返回结果时,调用strtod将值转成double类型。

取值源代码:

double zzlGetScore(unsigned char *sptr) { // t_zset.c:722

    unsigned char *vstr;

    unsigned int vlen;

    long long vlong;

    char buf[128];

    double score;

 

    serverAssert(sptr != NULL);

    serverAssert(ziplistGet(sptr,&vstr,&vlen,&vlong));

 

    if (vstr) {

        memcpy(buf,vstr,vlen);

        buf[vlen] = '\0';

        // 调用库函数strtod,

        // 如果值小于18014398509481983,能得到预期的值,

        // 否则总是返回18014398509481984。

        score = strtod(buf,NULL); // 字符串转double

    } else {

        score = vlong;

    }

 

    return score;

}

 

以字符串形式返回:

/* Add a double as a bulk reply */

void addReplyDouble(client *c, double d) { // networking.c:471

    char dbuf[128], sbuf[128];

    int dlen, slen;

    if (isinf(d)) {

        /* Libc in odd systems (Hi Solaris!) will format infinite in a

         * different way, so better to handle it in an explicit way. */

        addReplyBulkCString(c, d > 0 ? "inf" : "-inf");

    } else {

        dlen = snprintf(dbuf,sizeof(dbuf),"%.17g",d); // double转字符串

        slen = snprintf(sbuf,sizeof(sbuf),"$%d\r\n%s\r\n",dlen,dbuf);

        addReplyString(c,sbuf,slen);

    }

}

 

x86_64上的测试:

127.0.0.1:6379> del k1

(integer) 1

127.0.0.1:6379> zadd k1 18014398509481982 m1

(integer) 1

127.0.0.1:6379> zrange k1 0 -1 WITHSCORES

1) "m1"

2) "18014398509481982" 预期的值

127.0.0.1:6379> del k1

(integer) 1

127.0.0.1:6379> zadd k1 18014398509481983 m1

(integer) 1

127.0.0.1:6379> zrange k1 0 -1 WITHSCORES

1) "m1"

2) "18014398509481984" 非预期的值(和strtod相关)

 

127.0.0.1:6379> del k1

(integer) 1

127.0.0.1:6379> zadd k1 18014398509481982 m1

(integer) 1

127.0.0.1:6379> zrange k1 0 -1 WITHSCORES

1) "m1"

2) "18014398509481982" 预期的值

127.0.0.1:6379> zincrby k1 1 m1

"18014398509481984" 非预期的值

127.0.0.1:6379> zrange k1 0 -1 WITHSCORES

1) "m1"

2) "18014398509481984" 非预期的值

标签:127.0,zset,0.1,double,REdis,6379,k1,m1
来源: https://www.cnblogs.com/aquester/p/10769827.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有