0 前言
本文介绍使用C库自带的函数实现字符串转64位有符号数的方法,简单好用!
1 函数实现
/**
* @brief 计算数x的y次幂
*
* @param x 数x
* @param y y次幂
* @return 结果
*/
unsigned long long int pow_u64(unsigned long long int x, unsigned long long y)
{
unsigned long long i;
unsigned long long ret = 1;
if (y == 0)
{
return 1;
}
for (i = 0; i < y; i++)
{
ret *= x;
}
return ret;
}
/**
* @brief 字符串转64位有符号数
*
* @param str 10进制字符串
* @return long long int 结果
*/
long long int str_to_s64(char *str)
{
long long int ret;
long long int ret1;
long long int ret2;
long long int ret3;
int p1, p2, p3;
int len1, len2, len3;
int sign;
/* 用10进制表示s64最大的数长度为20 */
char str1[15] = {0};
char str2[15] = {0};
char str3[15] = {0};
int len = strlen(str);
if (len > 20)
{
return 0;
}
/* 跳过符号位 */
if (str[0] == '-')
{
sign = -1;
len -= 1;
}
else
{
sign = 1;
}
len1 = (float)len / 3;
len2 = (float)len / 3;
len3 = len - len2 - len1;
if (sign == -1)
{
p1 = 1;
p2 = 1 + len1;
p3 = 1 + len1 + len2;
}
else
{
p1 = 0;
p2 = 0 + len1;
p3 = 0 + len1 + len2;
}
/* 将字符串分3块处理 */
strncpy(str1, &str[p1], len1);
strncpy(str2, &str[p2], len2);
strncpy(str3, &str[p3], len3);
ret1 = atol(str1);
ret2 = atol(str2);
ret3 = atol(str3);
/* 还原数字 */
ret = ret1 * pow_u64(10, len2 + len3)
+ ret2 * pow_u64(10, len3)
+ ret3;
return sign * ret;
}
2 功能测试验证
2.1 负数测试
构造64位有符号数表示的所有负数字符串去测试字符串转64位有符号数函数显然是不现实的,64位有符号数能表示的最小值是:-9223372036854775808,
对应字符串长度为20。我们构造长度为1-20的负数字符串,传入我们设计好的str_to_s64函数,查看是否都能正确转换。函数如下设计:
void check_s64_value(void)
{
int i;
unsigned long long int val;
char str[25] = {0};
val = 0;
for (i = 0; i <= 18; i++)
{
val = -1 * pow_u64(10, i);
sprintf(str, "%lld", val);
if (str_to_s64(str) == val)
{
printf("[ OK ] Val : %lld\r\n", val);
printf(" Ret : %lld\r\n", str_to_s64(str));
}
else
{
printf("[FAIL] Val : %lld\r\n", val);
printf(" Ret : %lld\r\n", str_to_s64(str));
}
}
}
执行结果:
[ OK ] Val : -1
Ret : -1
[ OK ] Val : -10
Ret : -10
[ OK ] Val : -100
Ret : -100
[ OK ] Val : -1000
Ret : -1000
[ OK ] Val : -10000
Ret : -10000
[ OK ] Val : -100000
Ret : -100000
[ OK ] Val : -1000000
Ret : -1000000
[ OK ] Val : -10000000
Ret : -10000000
[ OK ] Val : -100000000
Ret : -100000000
[ OK ] Val : -1000000000
Ret : -1000000000
[ OK ] Val : -10000000000
Ret : -10000000000
[ OK ] Val : -100000000000
Ret : -100000000000
[ OK ] Val : -1000000000000
Ret : -1000000000000
[ OK ] Val : -10000000000000
Ret : -10000000000000
[ OK ] Val : -100000000000000
Ret : -100000000000000
[ OK ] Val : -1000000000000000
Ret : -1000000000000000
[ OK ] Val : -10000000000000000
Ret : -10000000000000000
[ OK ] Val : -100000000000000000
Ret : -100000000000000000
[ OK ] Val : -1000000000000000000
Ret : -1000000000000000000
可以看到1-20长度的负数字符串都被正确转换。
2.2 正数测试
构造64位有符号数表示的所有正数字符串去测试字符串转64位有符号数函数显然是不现实的,64位有符号数能表示的最大值是:9223372036854775807,
对应字符串长度为19。我们构造长度为1-19的正数字符串,传入我们设计好的str_to_s64函数,查看是否都能正确转换。函数如下设计:
void check_s64_value(void)
{
int i;
unsigned long long int val;
char str[25] = {0};
val = 0;
for (i = 0; i <= 18; i++)
{
val = pow_u64(10, i);
sprintf(str, "%lld", val);
if (str_to_s64(str) == val)
{
printf("[ OK ] Val : %lld\r\n", val);
printf(" Ret : %lld\r\n", str_to_s64(str));
}
else
{
printf("[FAIL] Val : %lld\r\n", val);
printf(" Ret : %lld\r\n", str_to_s64(str));
}
}
}
执行结果:
[ OK ] Val : 1
Ret : 1
[ OK ] Val : 10
Ret : 10
[ OK ] Val : 100
Ret : 100
[ OK ] Val : 1000
Ret : 1000
[ OK ] Val : 10000
Ret : 10000
[ OK ] Val : 100000
Ret : 100000
[ OK ] Val : 1000000
Ret : 1000000
[ OK ] Val : 10000000
Ret : 10000000
[ OK ] Val : 100000000
Ret : 100000000
[ OK ] Val : 1000000000
Ret : 1000000000
[ OK ] Val : 10000000000
Ret : 10000000000
[ OK ] Val : 100000000000
Ret : 100000000000
[ OK ] Val : 1000000000000
Ret : 1000000000000
[ OK ] Val : 10000000000000
Ret : 10000000000000
[ OK ] Val : 100000000000000
Ret : 100000000000000
[ OK ] Val : 1000000000000000
Ret : 1000000000000000
[ OK ] Val : 10000000000000000
Ret : 10000000000000000
[ OK ] Val : 100000000000000000
Ret : 100000000000000000
[ OK ] Val : 1000000000000000000
Ret : 1000000000000000000
可以看到1-19长度的正数字符串都被正确转换。