0

我有这段代码可以处理像“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 的补码中的值。如果我传递一个应该是十进制负数的十六进制字符串,我不会得到正确的结果。

4

2 回答 2

1

如果你不处理减号,它就不会处理自己。检查它,并记住你已经看到它的事实。然后,最后,如果您看到 a'-'作为第一个字符,则否定结果。

其他要点:

  • 您不需要(也不想)使用pow:它只是 results = format * results + digit每次都通过。
  • 您确实需要验证您的输入,确保您获得的数字在基数中是合法的(并且您没有任何其他奇数字符)。
  • 您还需要检查溢出。
  • 您应该使用isdigitand isalpha(或islowerand isupper)进行字符检查。
  • 您应该使用 eg val -= '0'(而不是48)从字符代码到数字值的转换。
  • 您应该使用[i], 而不是at(i)来读取单个字符。使用通常的开发选项进行编译,如果出现错误,您将得到崩溃,而不是异常。
  • 但是您可能应该使用迭代器而不是索引来遍历字符串。它更加地道。
  • 您几乎可以肯定地接受字母的大写和小写,并且可能也跳过前导空格。

从技术上讲,也不能保证字母字符是按顺序和相邻的。在实践中,我认为您可以依靠它来获取范围内的字符'A'-'F'(或 'a'-'f',但将字符转换为数字的最可靠方法是使用表查找。

于 2013-09-25T16:35:28.067 回答
0

You need to know whether the specified number is to be interpreted as signed or unsigned (in other words, is "ffffffff" -1 or 4294967295?). If signed, then to detect a negative number test the most-significant bit. If ms bit is set, then after converting the number as you do (generating an unsigned value) take the 1's complement (bitwise negate it then add 1).

Note: to test the ms bit you can't just test the leading character. If the number is signed, is "ff" supposed to be -1 or 255?. You need to know the size of the expected result (if 32 bits and signed, then "ffffffff" is negative, or -1. But if 64 bits and signed, "ffffffff' is positive, or 4294967295). Thus there is more than one right answer for the example "ffffffff".

Instead of testing ms bit you could just test if unsigned result is greater than the "midway point" of the result range (for example 2^31 -1 for 32-bit numbers).

于 2013-09-25T16:56:31.673 回答