redis中 ll2string() 和 string2ll() 的实现

2023-11-08

/* Convert a long long into a string. Returns the number of
 * characters needed to represent the number.
 * If the buffer is not big enough to store the string, 0 is returned.
 *
 * Based on the following article (that apparently does not provide a
 * novel approach but only publicizes an already used technique):
 *
 * https://www.facebook.com/notes/facebook-engineering/three-optimization-tips-for-c/10151361643253920
 *
 * Modified in order to handle signed integers since the original code was
 * designed for unsigned integers. */
// long long类型转C字符串,成功返回转换后字符串长度,失败返回0
// 修改以支持有符号整数,因为原始代码是为无符号整数设计的
int ll2string(char *dst, size_t dstlen, long long svalue) {
    static const char digits[201] =
        "0001020304050607080910111213141516171819"
        "2021222324252627282930313233343536373839"
        "4041424344454647484950515253545556575859"
        "6061626364656667686970717273747576777879"
        "8081828384858687888990919293949596979899";
    int negative;
    unsigned long long value;

    /* The main loop works with 64bit unsigned integers for simplicity, so
     * we convert the number here and remember if it is negative. */
	// 为了简单起见,主循环使用64位无符号整数,因此在这里转换数字,并记住是否为负数
    if (svalue < 0) {
        if (svalue != LLONG_MIN) {
            value = -svalue;
        } else {
            value = ((unsigned long long) LLONG_MAX)+1;
        }
        negative = 1;
    } else {
        value = svalue;
        negative = 0;
    }

    /* Check length. */
	// 确认预分配空间长度是否足够
    uint32_t const length = digits10(value)+negative;
    if (length >= dstlen) return 0;

    /* Null term. */
    uint32_t next = length;
    dst[next] = '\0';
    next--;
    while (value >= 100) {
        int const i = (value % 100) * 2;
        value /= 100;
        dst[next] = digits[i + 1];
        dst[next - 1] = digits[i];
        next -= 2;
    }

    /* Handle last 1-2 digits. */
    if (value < 10) {
        dst[next] = '0' + (uint32_t) value;
    } else {
        int i = (uint32_t) value * 2;
        dst[next] = digits[i + 1];
        dst[next - 1] = digits[i];
    }

    /* Add sign. */
    if (negative) dst[0] = '-';
    return length;
}
/* Convert a string into a long long. Returns 1 if the string could be parsed
 * into a (non-overflowing) long long, 0 otherwise. The value will be set to
 * the parsed value when appropriate.
 *
 * Note that this function demands that the string strictly represents
 * a long long: no spaces or other characters before or after the string
 * representing the number are accepted, nor zeroes at the start if not
 * for the string "0" representing the zero number.
 *
 * Because of its strictness, it is safe to use this function to check if
 * you can convert a string into a long long, and obtain back the string
 * from the number without any loss in the string representation. */
// C字符串转long long 类型,成功返回1
int string2ll(const char *s, size_t slen, long long *value) {
    const char *p = s;
    size_t plen = 0;
    int negative = 0;
    unsigned long long v;

    /* A zero length string is not a valid number. */
	// ERR: 入参字符串为空
    if (plen == slen)
        return 0;

    /* Special case: first and only digit is 0. */
	// 开头为0,且只有1个字符
    if (slen == 1 && p[0] == '0') {
        if (value != NULL) *value = 0;
        return 1;
    }

    /* Handle negative numbers: just set a flag and continue like if it
     * was a positive number. Later convert into negative. */
	// 判断是否为负数
    if (p[0] == '-') {
        negative = 1;
        p++; plen++;

        /* Abort on only a negative sign. */
		// ERR: 只有1个负号
        if (plen == slen)
            return 0;
    }

    /* First digit should be 1-9, otherwise the string should just be 0. */
	// 最高位应该为 1~9
    if (p[0] >= '1' && p[0] <= '9') {
        v = p[0]-'0';
        p++; plen++;
    } else {
        return 0;
    }

    /* Parse all the other digits, checking for overflow at every step. */
	// 剩余位数应该为 0~9
    while (plen < slen && p[0] >= '0' && p[0] <= '9') {
        if (v > (ULLONG_MAX / 10)) // 溢出 /* Overflow. */
            return 0;
        v *= 10;

        if (v > (ULLONG_MAX - (p[0]-'0'))) // 溢出 /* Overflow. */
            return 0;
        v += p[0]-'0';

        p++; plen++;
    }

    /* Return if not all bytes were used. */
	// ERR: 有字符不是数字
    if (plen < slen)
        return 0;

    /* Convert to negative if needed, and do the final overflow check when
     * converting from unsigned long long to long long. */
	// 符号处理,并判断是否溢出
    if (negative) {
        if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* Overflow. */
            return 0;
        if (value != NULL) *value = -v;
    } else {
        if (v > LLONG_MAX) /* Overflow. */
            return 0;
        if (value != NULL) *value = v;
    }
    return 1;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

redis中 ll2string() 和 string2ll() 的实现 的相关文章

随机推荐

  • Open3D (C++) 基于拟合平面的点云地面点提取

    目录 一 算法原理 1 原理概述 2 参考文献 二 代码实现 三 结果展示 1 原始点云 2 提取结果 四 相关链接 系列文章 连载中 Open3D C 基于高程的点云地面点提取 Open3D C 基于拟合平面的点云地面点提取 Open3D
  • IIS 运行bat文件,实现动态网站的建立

    前言 我的感觉是这篇博客写出来 也没人会看 因为在这个过程中我遇到了很多困难 很难找到解决办法 我解决的过程都是分解问题找相似的解决办法 但是仍然找了很久 问题的初遇 要说这个问题是怎么想出来的 那我自然不会这么无聊而且有本事想出这个问题
  • 我是如何把SpringBoot项目的并发提升十倍量级的

    背景 生产环境偶尔会有一些慢请求导致系统性能下降 吞吐量下降 下面介绍几种优化建议 方案 1 undertow替换tomcat 电子商务类型网站大多都是短请求 一般响应时间都在100ms 这时可以将web容器从tomcat替换为undert
  • 如何保证接口安全,做到防篡改防重放?

    对于互联网来说 只要你系统的接口暴露在外网 就避免不了接口安全问题 如果你的接口在外网裸奔 只要让黑客知道接口的地址和参数就可以调用 那简直就是灾难 举个例子 你的网站用户注册的时候 需要填写手机号 发送手机验证码 如果这个发送验证码的接口
  • 在Win10系统中用mimikatz抓取明文密码

    实验环境 Windows10专业版 参考了网上的方法 发现大部分都是抄的 https blog csdn net netsec steven article details 107257325 这一篇文章 都被转烂了 这一篇文章是对的 但是
  • 双层pdf-不用手动添加目录超链接教程

    双层pdf最大的特点是文件既可以是文本型的 比如由word生成的文件 也可以是图像型的 既可以100 保留原始版面效果 又便于建立索引数据库 进行科学的管理 在标书中应用广泛 使用软件 word Adobe Acrobat DC 以前生成双
  • 使用VsCode进行webpack打包

    前言 折腾了两天 折腾的有点伤心 以往的项目是站在大树地下使用框架自带的打包框架 当自己用webpack来实现自动打包的时候却发现 各种红 当自己把环境搭建好写出第一个demo的时候就发现这些过程都是很经验的积累吧 第一步 确保安装node
  • 深度学习 vs 概率图模型 vs 逻辑学

    深度学习 vs 概率图模型 vs 逻辑学 发表于 2015 04 30 21 55 1359次阅读 来源 quantombone 0 条评论 作者 Tomasz Malisiewicz 深度学习 deep learning 图模型 人工智能
  • TEA加密算法及JAVA实现

    TEA算法由剑桥大学计算机实验室的David Wheeler和Roger Needham于1994年发明 它是一种分组密码算法 其明文密文块为64比特 密钥长度为128比特 TEA算法利用不断增加的Delta 黄金分割率 值作为变化 使得每
  • 【华为OD机试】计算最大乘积【2023 B卷

    华为OD机试 真题 点这里 华为OD机试 真题考点分类 点这里 题目描述 给定一个元素类型为小写字符串的数组 请计算两个没有相同字符的元素长度乘积的最大值 如果没有符合条件的两个元素 返回0 输入描述 输入为一个半角逗号分隔的小写字符串的数
  • sessionStorage使用不同方法打开新页面

    sessionStorage 属性允许你访问一个 对应当前源的 session Storage 对象 它与 localStorage 相似 不同之处在于 localStorage 里面存储的数据没有过期时间设置 而存储在 sessionSt
  • listView 中relativeLayout 布局的 android:layout_alignParentBottom="true" 无效的解决办法

    listView 中relativeLayout 布局的 android layout alignParentBottom true 无效的解决办法 分类 Android 2011 05 10 11 14 9234人阅读 评论 4 收藏 举
  • 动态代理:如何深入理解和分析,不如手写一个(源码包分析、楼主亲测)

    如何分类Java语言 Java是静态的强类型语言 但是因为提供了类似反射等机制 也具备了部分动态语言的能力 一 动态代理的简单描述 动态代理是一种方便运行时动态构建代理 动态处理代理方法调用的机制 很多场景都是利用类似的机制做到的 比如用来
  • 设置项目中的logback.xml日志打印信息

    针对于Springboot项目 设置 logback日志信息格式化打印
  • javascript中(function($){...})(jQuery)写法是什么意思

    在javascript中 function jQuery 的写法是什么意思 这是一条分割线 首先 function arg 这种形式的在javascript中称之为匿名函数 arg则是匿名函数的参数 而 function jQuery 这种
  • 序列模型——自然语言处理与词嵌入(理论部分)

    1 词汇表征 深度学习已经给自然语言处理 Natural Language Process NLP 带来革命性的变革 其中一个很关键的概念是词嵌入 word embedding 这是语言表示的一种方式 可以让算法自动的了解一些类似的词 例如
  • JAVA版的数据结构——链表

    目录 1 单向不带头链表 1 1 链表的概念及结构 1 2 代码部分 1 3 完整的全部代码 2 双向不带头链表 2 1 代码部分 2 2 完整的代码 3 MySingleList与MyLinkedList代码上的区别 4 LinkedLi
  • oracle重复数据取只一条,oracle 一个表多条重复记录只取一条的解决方法

    A 表 id name 1 张三 2 李四 B 表 id 为 A 表 主键 id name 1 王五 1 小李 1 王八 2 赵四 2 李五 需要的结果为 1 张三 王五 2 李四 赵四 SQL 语句为 select from a t5 l
  • 这才是打开软件品质保证工程师(SQA)职责的正确姿势

    综合IEEE SQA的定义 ISO9000 3 的相关章节 CMM要求 更为清晰及详细的SQA职责定义应该如下 Daniel Galin Software Quality Assurance 通过采取系统的 有计划的必要措施 为软件开发的整
  • redis中 ll2string() 和 string2ll() 的实现

    Convert a long long into a string Returns the number of characters needed to represent the number If the buffer is not b