REdis zset和double

 

平臺:x86_64函數

結論:Zset的最大分數不要超過1801439850948198217位數字,54位二進制),不然不會獲得指望的值。測試

REdis5.0.4spa

 

Zset採用double存儲分數值(score),而incrbyfloathincrbyfloat採用的是long double存儲數值。orm

 

double自己是能夠存儲比1801439850948198217位數字,54位二進制)大的值,好比18014398509481983(也是17位數字,54位二進制)。但REdis在返回結果時,調用strtod將值轉成double類型。server

取值源代碼:blog

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

    unsigned char *vstr;ci

    unsigned int vlen;字符串

    long long vlong;it

    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(2的54次方)。

        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" 非預期的值

 

附:C/C++浮點知識圖譜

 

相關文章
相關標籤/搜索