前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >REdis zset和double

REdis zset和double

作者头像
一见
发布2019-05-10 10:56:33
1.4K0
发布2019-05-10 10:56:33
举报
文章被收录于专栏:蓝天蓝天

平台: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(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++浮点知识图谱

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-04-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档