有符号十六进制字符串转 long int 函数
我需要一个函数将 32 位或 24 位有符号(二进制补码)十六进制字符串转换为 long int。需要在 32 位和 64 位机器上工作(无论 long int 的大小),并且无论机器是否是二进制补码机器都可以工作。
解决方案:
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;
}
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
对于 24 位字符串:
当您解析十六进制字符串时,标准
strtol
函数会将其读取为0 -> 0 范围内的无符号值。 2^24 - 1
。范围
0 -> 2^23 - 1
是正确的,但范围2^23 -> 2^24 - 1
需要映射到-2^23 -> -1
这是一个简单的减法,可以按如下方式执行。要使用相同的技术转换 32 位字符串,您必须使用可以以有符号类型表示完整 32 位无符号整数的中间类型来执行减法。
long long int
保证是 64 位,因此您可以使用它。例如
For a 24-bit string:
When you parse the hex string, the standard
strtol
function will read it as an unsigned value in the range0 -> 2^24 - 1
.The range
0 -> 2^23 - 1
is correct, but the range2^23 -> 2^24 - 1
needs to be mapped to-2^23 -> -1
which is a simple subtraction which can be performed as follows.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.
我们有一个
SIGN_EXTEND
宏,如下所示:它依赖于
>>
运算符 1 - 在设置符号位时填充输入。使用它:对于您的问题,您可以使用:
We have a
SIGN_EXTEND
macro, that looks like:It relies on the
>>
operator 1-filling the input when the sign bit is set. Use it like:For your problem, you could use:
这种比较是错误的:
if (toupper (string[0]) == 'F')
您需要使用 MSB 集对任何值进行符号扩展,例如:
if(strchr("89ABCDEF", toupper(string[0])) != NULL)
This comparison is wrong:
if (toupper (string[0]) == 'F')
You'll need to sign-extend for any value with the MSB set, so something like:
if(strchr("89ABCDEF", toupper(string[0])) != NULL)
有没有理由不能将 strtol 与基数 16 一起使用?
Is there a reason why you cannot use strtol with radix 16?
这将产生具有正确符号的数字。
这总是会产生积极的结果
this will produce number with correct sign.
this will always produce positive result