问题
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 justresults = format * results + digiteach 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
isdigitandisalpha(orislowerandisupper) for you character checking. - You should use e.g.
val -= '0'(and not48) for your conversion from character code to digit value. - You should use
[i], and notat(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