且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

签名十六进制字符串长整型函数

更新时间:2023-11-05 14:44:40

有关的24位字符串:

在解析十六进制字符串,标准的与strtol 函数将它读作范围 0的无符号值 - > 2 ^ 24 - 1

范围 0 - > 2 ^ 23 - 1 是正确的,但幅度 2 ^ 23 - >需要1 映射到 -2 ^ 23 - - 2 ^ 24 GT; -1 这是一个可以作为进行一个简单的减法如下:

 如果(结果> =(1L<< 23))
    结果 - =(1L<< 24);

要使用你必须使用一个中间类型,它可以重新present一个完整的32位无符号整数的署名类型执行减法同样的技术转换的32位串。 A 得到long long int 保证是64位​​的,因此您可以使用此功能。

例如

 长整型ParseHexStr(为const char *中,INT位)
{
    字符* endptr;
    得到long long int的结果;    结果=与strtoll(中,和放大器; endptr,16);    / *
    ** TODO - 错误检查,例如检查endptr!=在
    **同时检查范围错误,由LLONG_MIN信号
    ** LLONG_MAX和错误号== ERANGE。
    * /    如果(导致与GT; =(1LL&所述;≤(位 - 1))
        结果 - =(1LL<<位);    返回结果;
}

I need a function to convert a 32bit or 24bit signed (in two's complement) hexadecimal string into a long int. Needs to work on both 32bit and 64bit machines (regardless of the size of long int) and work regardless of whether the machine is a two's complement machine or not.

SOLUTION:

long int hex2li (char hexStr[], int signedHex)
{
   int bits = strlen (hexStr) * 4;

   char *pEnd;
   long long int result = strtoll (hexStr, &pEnd, 16);

   if (pEnd[0] == '\0')
   {
      if (signedHex)
      {
         if (result >= (1LL << (bits - 1))) result -= (1LL << bits);
      }

      return (long int) result;
   }

   return LONG_MIN;
}

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;
}