C++ Convert Hex String to Signed Integer

C++ convert hex string to signed integer

use std::stringstream

unsigned int x;   
std::stringstream ss;
ss << std::hex << "fffefffe";
ss >> x;

the following example produces -65538 as its result:

#include <sstream>
#include <iostream>

int main() {
unsigned int x;
std::stringstream ss;
ss << std::hex << "fffefffe";
ss >> x;
// output it as a signed type
std::cout << static_cast<int>(x) << std::endl;
}

In the new C++11 standard, there are a few new utility functions which you can make use of! specifically, there is a family of "string to number" functions (http://en.cppreference.com/w/cpp/string/basic_string/stol and http://en.cppreference.com/w/cpp/string/basic_string/stoul). These are essentially thin wrappers around C's string to number conversion functions, but know how to deal with a std::string

So, the simplest answer for newer code would probably look like this:

std::string s = "0xfffefffe";
unsigned int x = std::stoul(s, nullptr, 16);

NOTE: Below is my original answer, which as the edit says is not a complete answer. For a functional solution, stick the code above the line :-).

It appears that since lexical_cast<> is defined to have stream conversion semantics. Sadly, streams don't understand the "0x" notation. So both the boost::lexical_cast and my hand rolled one don't deal well with hex strings. The above solution which manually sets the input stream to hex will handle it just fine.

Boost has some stuff to do this as well, which has some nice error checking capabilities as well. You can use it like this:

try {
unsigned int x = lexical_cast<int>("0x0badc0de");
} catch(bad_lexical_cast &) {
// whatever you want to do...
}

If you don't feel like using boost, here's a light version of lexical cast which does no error checking:

template<typename T2, typename T1>
inline T2 lexical_cast(const T1 &in) {
T2 out;
std::stringstream ss;
ss << in;
ss >> out;
return out;
}

which you can use like this:

// though this needs the 0x prefix so it knows it is hex
unsigned int x = lexical_cast<unsigned int>("0xdeadbeef");

Convert a variable size hex string to signed number (variable size bytes) in C#

The easiest way I can think of converting 12 bit signed hex to a signed integer is as follows:

string value = "FFF";    
int convertedValue = (Convert.ToInt32(value, 16) << 20) >> 20; // -1

The idea is to shift the result as far left as possible so that the negative bits line up, then shift right again to the original position. This works because a "signed shift right" operation keeps the negative bit in place.

You can generalize this into a method as follows:

int Convert(string value, int fromBase, int bits)
{
int bitsToShift = 32 - bits;
return (Convert.ToInt32(value, fromBase) << bitsToShift) >> bitsToShift;
}

You can cast the result to a short if you want a 16 bit value when working with 12 bit hex strings. Performance of this method will be the same as a 16 bit version because bit shift operators on short cast the values to int anyway and this gives you more flexibility to specify more than 16 bits if needed without writing another method.

how to get a signed int from an unsigned hex in C++?

Completing the 2 complement with the most significant byte should work fine:

#include <iostream>

int main () {

int a = 0xfffef1;
a |= 0xff << 24;
std::cout << a << std::endl;
}

See the Live Demo.

How do I convert hex string into signed integer?

My solution was to put the first take the first 8 bits of the 16 bit integer and store them in an sbyte.

Signed Hexadecimal string to long int function

For a 24-bit string:

When you parse the hex string, the standard strtol function will read it as an unsigned value in the range 0 -> 2^24 - 1.

The range 0 -> 2^23 - 1 is correct, but the range 2^23 -> 2^24 - 1 needs to be mapped to -2^23 -> -1 which is a simple subtraction which can be performed as follows.

if (result >= (1L << 23))
result -= (1L << 24);

To convert a 32-bit string using the same technique you have to use an intermediate type that can represent a full 32-bit unsigned integer in a signed type for performing the subtraction. A long long int is guaranteed to be 64-bits so you can use this.

E.g.

long int ParseHexStr(const char *in, int bits)
{
char* endptr;
long long int result;

result = strtoll(in, &endptr, 16);

/*
** TODO - error checking, e.g. check endptr != in
** Also check for range errors, signalled by LLONG_MIN
** LLONG_MAX and a errno == ERANGE.
*/

if (result >= (1LL << (bits - 1))
result -= (1LL << bits);

return result;
}

8 bit hex string to signed integer

Type casting is not safe but you really need it.

NSString *tempNumber = @"FB";
NSScanner *scanner = [NSScanner scannerWithString:tempNumber];
unsigned int temp;
[scanner scanHexInt:&temp];
int actualInt = (char)temp; //why char because you have 8 bit integer
NSLog(@"%@:%d:%d",tempNumber, temp, actualInt);

Console output: FB:251:-5



Related Topics



Leave a reply



Submit