I'm trying to cast a signed hex number to WORD, DWORD and QWORD by this way:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
int main(void) {
printf("WORD=%d\n", (int16_t) strtol("F123", NULL, 16));
printf("DWORD=%d\n", (int32_t) strtol("FFFFF123", NULL, 16));
printf("QWORD=%lld\n", (int64_t) strtol("FFFFFFFFFFFFF123", NULL, 16));
return 0;
}
But it returns the following:
WORD=-3805
DWORD=2147483647
QWORD=2147483647
But why the DWORD and QWORD castings are not returning -3805
too?
I mean: 0xFFFFF123
stored in a DWORD would contain -3805
value in decimal, not 2147483647
Expected output:
WORD=-3805
DWORD=-3805
QWORD=-3805
Do you have an bitwise alternative to do it?
0xFFFFF123 is out of the range of a long int if a long int have 32 bit, so strtol() return LONG_MAX (0x7FFFFFFF = 2147483647 in our case).
use strtoull() to convert a string to a unsigned integer with at least 64 bits, and allways check for errors before proceed.
For print a integer with a specified bit size, use something like this:
printf("foo=%"PRIu32"\n",(uint32_t) foo);
a better way:
#include <stdio.h>
#include <stdlib.h>
#define __STDC_FORMAT_MACROS //we need that for PRI[u]8/16/32 format strings
#include <inttypes.h>
#include <errno.h>
void error_exit(void)
{
perror("ups");
exit(EXIT_FAILURE);
}
int main(void)
{
unsigned long long temp;
errno=0;
temp = strtoull("FFFFF123", NULL, 16);
if(errno)
{
error_exit();
}
printf("DWORD=%"PRId32"\n", (int32_t) temp );
errno=0;
temp = strtoull("FFFFFFFFFFFFF123", NULL, 16);
if(errno)
{
error_exit();
}
printf("QWORD=%"PRId64"\n", (int64_t) temp );
return EXIT_SUCCESS;
}