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

REdis zset和double的更多相关文章

  1. 实现排行榜神器——redis zset

    需求:假如现在需要搞个 “运动消耗卡路里排行榜”,例似微信步数排名,显示排名前20人的信息和消耗的卡里路,怎样实现排序? 一般思路:存储信息,然后数据库查询,排序?(假如有几十万人参与排名,这样查my ...

  2. 延时任务-基于redis zset的完整实现

    所谓的延时任务给大家举个例子:你买了一张火车票,必须在30分钟之内付款,否则该订单被自动取消.订单30分钟不付款自动取消,这个任务就是一个延时任务. 我之前已经写过2篇关于延时任务的文章: <完 ...

  3. Redis ZSet 有序集合

    有序集合类型与集合类型的区别就是他是有序的.有序集合是在集合的基础上为每一个元素关联一个分数,这就让有序集合不仅支持插入,删除,判断元素是否存在等操作外,还支持获取分数最高/最低的前N个元素.有序集合 ...

  4. redis zset底层实现原理

    一.Zset编码的选择 1.有序集合对象的编码可以是ziplist或者skiplist.同时满足以下条件时使用ziplist编码: 元素数量小于128个 所有member的长度都小于64字节 其他: ...

  5. Redis ZSet Type

    Redis有序集合的操作命令和对应的api如下: zadd [zset] sco 'value' JedisAPI:public Long zadd(final String key, final d ...

  6. 将mysql表数据批量导入redis zset结构中

    工作中有这样一个需求,要将用户的魅力值数据做排行,生成榜单展示前40名,每隔5分钟刷新一次榜单.这样的需求用redis的zset是很方便实现的.但是数据存在mysql的表中,有400多万条,怎么将其快 ...

  7. Redis学习第六课:Redis ZSet类型及操作

    Sorted set是set的一个升级版本,它在set的基础上增加了一个顺序属性,这一属性在添加修改元素时候可以指定,每次指定后,zset会自动重新按新的值调整顺序.可以理解为有两列字段的数据表,一列 ...

  8. (PHP)redis Zset(有序集合 sorted set)操作

    /** * * Zset操作 * sorted set操作 * 有序集合 * sorted set 它在set的基础上增加了一个顺序属性,这一属性在修改添加元素的时候可以指定,每次指定后,zset会自 ...

  9. C# 通过ServiceStack 操作Redis——ZSet类型的使用及示例

    Sorted Sets是将 Set 中的元素增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列 /// <summary> /// Sorted Sets是将 ...

随机推荐

  1. pl/sql developer 问题总结

    问题1,出现NLS_LANG和字符集(Character set)问题 安装完PL/SQL后打开,遇到如图问题. 原因:这是因为系统没有设置NLS_LANG系统变量. 解决方法:有两种方式查看. 1. ...

  2. python--第二十一/二天总结

    Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块. 1 2 3 ...

  3. 利用百度编辑器和IIS限制文件上传的大小

    1.百度编辑器的大小限制 针对不同的文件类型限制大小 例如图片是imageMaxSize ,依次类推 /* 前后端通信相关的配置,注释只允许使用多行方式 */ {     /* 上传图片配置项 */ ...

  4. HBase Master HA高可用

    HMaster没有单点问题,HBase中可以启动多个HMaster,通过Zookeeper的Master Election机制保证总有一个Master运行. 所以这里要配置HBase高可用的话,只需要 ...

  5. js 中格式化显示时间

    function getMyDateTime(str){ var oDate = new Date(str), oYear = oDate.getFullYear(), oMonth = oDate. ...

  6. 重构现有代码:Refactoring

    重构现有代码:Refactoring 1.WHY SHOULD WE REFACTOR? 1.Refactoring Improves the Design of Software Without r ...

  7. 正向与反向拓扑排序的区别(hdu 1285 确定比赛名次和hdu 4857 逃生)

    确定比赛名次 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...

  8. nio实现原理

    nio是事件驱动,当soket有消息过来时才开启线程,bio每当有连接时,就开启一个线程,长连接的话,就有太多的空闲连接占用线程内存 nio是非阻塞长连接 ServerSocketChannel:饭店 ...

  9. ios OC 关键字 copy,strong,weak,assign的区别

    一.先介绍 copy.strong.weak 的区别,如代码所示 @property(copy,nonatomic)NSMutableString*aCopyMStr; @property(stron ...

  10. Python中__init__和self的意义和作用

    由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去.以学生类为例,通过定义一个特殊的__init__方法,在创建实例的时候,就把name,score等属性绑 ...