我有这段代码来处理像"19485"或"10011010"或"AF294EC"这样的字符串......
long long toDecimalFromString(string value, Format format){
long long dec = 0;
for (int i = value.size() - 1; i >= 0; i--) {
char ch = value.at(i);
int val = int(ch);
if (ch >= '0' && ch <= '9') {
val = val - 48;
} else {
val = val - 55;
}
dec = dec + val * (long long)(pow((int) format, (value.size() - 1) - i));
}
return dec;
}
此代码适用于所有不在 2 补码中的值。如果我传递一个十六进制字符串,它应该是十进制的负数,我没有得到正确的结果。
如果你不处理减号,它就不会处理自己。检查它,并记住你看到它的事实。 然后,在结尾,如果你看到'-'
作为第一个字符,则否定结果。
其他要点:
- 你不需要(也不想(使用
pow
:它只是 每次都results = format * results + digit
通过。 - 您确实需要验证您的输入,确保数字您获得的在基地是合法的(并且您没有任何其他奇怪的字符(。
- 您还需要检查是否溢出。
- 您应该使用
isdigit
和isalpha
(或islower
和isupper
(为您进行字符检查。 - 您应该使用例如
val -= '0'
(而不是48
(为您的从字符代码转换为数字值。 - 你应该使用
[i]
,而不是at(i)
,来阅读个人字符。 使用通常的开发选项进行编译,以及如果发生错误,您将获得崩溃,而不是异常。 - 但是你可能应该使用迭代器,而不是索引,去通过字符串。 它更惯用。
- 您几乎肯定应该接受大写和小写对于阿尔法,可能还会跳过前导空格。
从技术上讲,也不能保证字母顺序字符是有序和相邻的。 在实践中,我认为你可以依靠它来计算'A'-'F'
范围内的字符(或 'a'-'f'
,但将字符转换为数字的最可靠方法是使用表查找。
你需要知道指定的数字是被解释为有符号还是无符号(换句话说,"fffff" 是 -1 还是 4294967295?(。如果签名,则检测负数测试最高有效位。如果设置了ms位,则在转换数字(生成无符号值(后,取1的补码(按位取反,然后加1(。
注意:要测试 ms 位,您不能只测试前导字符。如果数字是有符号的,"ff"应该是 -1 还是 255?您需要知道预期结果的大小(如果 32 位并有符号,则 "fffff" 为负数,或 -1。但如果 64 位并有符号,"ffffff" 是正数,或 4294967295(。因此,示例"ffff
与其测试 ms bit,不如测试无符号结果是否大于结果范围的"中间点"(例如 2^31 -1 表示 32 位数字(。