Convert hex- bin- or decimal string to long long in C++

痞子三分冷 提交于 2019-12-13 07:46:49

问题


I have this code which handles Strings like "19485" or "10011010" or "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;
}

this code works for all values which are not in 2's complement. If I pass a hex-string which is supposed to be a negativ number in decimal I don't get the right result.


回答1:


If you don't handle the minus sign, it won't handle itself. Check for it, and memorize the fact you've seen it. Then, at the end, if you'd seen a '-' as the first character, negate the results.

Other points:

  • You don't need (nor want) to use pow: it's just results = format * results + digit each time through.
  • You do need to validate your input, making sure that the digit you obtain is legal in the base (and that you don't have any other odd characters).
  • You also need to check for overflow.
  • You should use isdigit and isalpha (or islower and isupper) for you character checking.
  • You should use e.g. val -= '0' (and not 48) for your conversion from character code to digit value.
  • You should use [i], and not at(i), to read the individual characters. Compile with the usual development options, and you'll get a crash, rather than an exception, in case of error.
  • But you should probably use iterators, and not an index, to go through the string. It's far more idiomatic.
  • You should almost certainly accept both upper and lower case for the alphas, and probably skip leading white space as well.

Technically, there's also no guarantee that the alphabetic characters are in order and adjacent. In practice, I think you can count on it for characters in the range 'A'-'F' (or 'a'-'f', but the surest way of converting character to digit is to use table lookup.




回答2:


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).



来源:https://stackoverflow.com/questions/19010032/convert-hex-bin-or-decimal-string-to-long-long-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!