redis中 ll2string() 和 string2ll() 的实现
2021/11/23 2:12:14
本文主要是介绍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 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; }
这篇关于redis中 ll2string() 和 string2ll() 的实现的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-24Redis资料:新手入门快速指南
- 2024-12-24Redis资料:新手入门教程与实践指南
- 2024-12-24Redis资料:新手入门教程与实践指南
- 2024-12-07Redis高并发入门详解
- 2024-12-07Redis缓存入门:新手必读指南
- 2024-12-07Redis缓存入门:新手必读教程
- 2024-12-07Redis入门:新手必备的简单教程
- 2024-12-07Redis入门:新手必读的简单教程
- 2024-12-06Redis入门教程:从安装到基本操作
- 2024-12-06Redis缓存入门教程:轻松掌握缓存技巧