How to cast void* to long long in C? - c

I am using a 32-bit system. I wanted to cast void* to long long(64-bit). I have tried as below and I am not getting expected values.
printf("size of long long is %d and unsigned int is %d\n", sizeof(long long), sizeof(unsigned int));
void* ptr = 12340000;
long long test = (long long)ptr;
printf("the value of the ptr is %d\n", ptr);
printf("the value of the test is %d\n", test);
The output for the above code is:
size of long long is 8 and unsigned int is 4
the value of the ptr is 12340000
the value of the test is 1610658408

Let's start with getting the format strings match the types you pass.
#include <stdio.h>
int main(void)
{
printf("size of long long is %zu and unsigned int is %zu\n", sizeof(long long), sizeof(unsigned int));
void* ptr = (void *) 12340000;
long long test = (long long) ptr;
printf("the value of the ptr is %p\n", ptr);
printf("the value of the test is %lld\n", test);
}
If you want to check text in hexadecimal (hint: use %llx) you will see it is probably the same as ptr in a slightly different representation. You shouldn't cast a void * to long long without testing if that actually provides the correct results on your platform.
But be very careful with format strings. For sizeof you should use %zu, for void * it is %p and for long long it is %lld.
The cast to long long is just: (long long).

Related

Print correct format from double value to hexadecimal

#include <stdio.h>
typedef unsigned char*pointer;
void show_bytes(pointer start, size_t len)
{
size_t i;
for (i = 0; i < len; i++)
printf("%p\t0x%04x\n",start+i, start[i]);
printf("\n");
}
int main()
{
double a = 4.75;
printf("Double demo by %s on %s %s\n", "Toan Tran", __DATE__, __TIME__);
printf("Double a = %.2f (0x%08x)\n", a, a);
show_bytes((pointer) &a, sizeof(double));
}
Output:
Double demo by Toan Tran on Nov 8 2018 11:07:07
Double a = 4.75 (0x00000100)
0x7ffeee7a0b38 0x0000
0x7ffeee7a0b39 0x0000
0x7ffeee7a0b3a 0x0000
0x7ffeee7a0b3b 0x0000
0x7ffeee7a0b3c 0x0000
0x7ffeee7a0b3d 0x0000
0x7ffeee7a0b3e 0x0013
0x7ffeee7a0b3f 0x0040
For this line:
printf("Double a = %.2f (0x%08x)\n", a, a);
I want it to print out the result of start[i]
The return hexadecimal is not the right value for double.
I want it to return 0x40130000000000...
Please help.
The %x format specifier is expecting an unsigned int argument, but you're passing in a double. Using the wrong format specifier invokes undefined behavior.
To print the representation of a double, you need to print each individual byte as hex using a character pointer. This is exactly what you're doing in show_bytes, and is the proper way to do this.
Also, when printing a pointer with the %p format specifier, you should cast the pointer to void *, which is what %p expects. This is one of the rare cases where a cast to void * is needed.
You might be tempted to do something like this:
printf("%llx", *((unsigned long long *)&a));
However this is a violation of the strict aliasing rule. You would need to use memcpy to copy the bytes to the other type:
static_assert(sizeof(unsigned long long) == sizeof(double));
unsigned long long b;
memcpy(&b, &a, sizeof(a));
printf("%llx", b);
You can also do this with a union:
union dval {
double d;
unsigned long long u;
};
union dval v;
v.d = d;
printf("%llx", v.u);
To allow printing a hex dump of any object, pass its address and length.
void show_bytes2(void *start, size_t size) {
int nibble_width_per_byte = (CHAR_BIT + 3) / 4; // Often 2
unsigned char *mem = start;
// Highest bytes first
for (size_t i = size; i>0; ) {
printf("%0*x", nibble_width_per_byte, mem[--i]);
}
printf("\n");
// Lowest bytes first
while (size--) {
printf("%0*x", nibble_width_per_byte, *mem++);
}
printf("\n");
}
Use "%a" to print the significand of the double in hexadecimal.
int main() {
double a = 4.75;
printf("Double a = %a %e %f %g\n", a, a, a, a);
show_bytes2(&a, sizeof a);
}
Output
Double a = 0x1.3p+2 4.750000e+00 4.750000 4.75
4013000000000000 // I want it to return 0x40130000000000...
0000000000001340

Casting Long to Unsigned Short Int / Strtol

There is no compile error. However, the results are not expected. My suspicion is that the casting long to unsigned short int is causing the error. How can I safely cast long to a short for Hex?
[Requiriments: Convert a row of string (which has numbers) to unsigned short int] Thanks!
unsigned short int str_to_bin (char* instr_bin_str) {
unsigned short int i = 0;
long j;
char* ptr;
j = strtol (instr_bin_str, &ptr, 10);
if (j == 0) {
fprintf (stderr, "error6: str_to_bin() failed");
return 6;
}
i = (unsigned short) j;
printf("State: 0x%X \n", i);
return i;
}
The string you're passing in is the binary representation of a number. However, when you're calling strtol you pass in 10 for the third parameter, which means it expects a string in decimal representation.
If you're expecting binary, you need to tell strtol to expect that:
j = strtol (instr_bin_str, &ptr, 2);

Errors compiling C code with sizeof from command line

I wrote the following code in Nano from the Linux command line to get errors when compiling:
I'd like to know what I need to change in my code to make it compile properly. I am trying to get the number of bits in each data type listed to print on a single line.
#include<stdio.h>
int main(void){
char A;
unsigned char B;
int a;
unsigned int b;
long c;
unsigned long d;
float e;
double f;
long double g;
printf(
"%c %c %i %u %li %lu %f %lf %Lf\n",
sizeof(char), sizeof(unsigned char),
sizeof(int), sizeof(unsigned int),
sizeof(long), sizeof(unsigned long),
sizeof(float), sizeof(double), sizeof(long double)
);
return 0;
}
The sizeof operator returns an integer of type size_t, so you should use the appropriate printf format specifier ("%zu") (assuming C99):
printf(
"%zu %zu %zu %zu %zu %zu %zu %zu %zu\n",
sizeof(char), sizeof(unsigned char),
sizeof(int), sizeof(unsigned int),
sizeof(long), sizeof(unsigned long),
sizeof(float), sizeof(double), sizeof(long double)
);
However, this prints the number of bytes in each type. If you want the number of bits in each type, include <limits.h> and multiply each result by CHAR_BIT to get that:
#include <limits.h>
/* ... */
printf(
"%zu %zu %zu %zu %zu %zu %zu %zu %zu\n",
sizeof(char) * CHAR_BIT, sizeof(unsigned char) * CHAR_BIT,
sizeof(int) * CHAR_BIT, sizeof(unsigned int) * CHAR_BIT,
sizeof(long) * CHAR_BIT, sizeof(unsigned long) * CHAR_BIT,
sizeof(float) * CHAR_BIT, sizeof(double) * CHAR_BIT, sizeof(long double) * CHAR_BIT
);
IMO, it would look much clearer if you label what you're printing and print each value on its own line, like this:
printf("Number of bits in char = %zu\n", sizeof(char) * CHAR_BIT);
printf("Number of bits in unsigned char = %zu\n", sizeof(unsigned char) * CHAR_BIT);
printf("Number of bits in int = %zu\n", sizeof(int) * CHAR_BIT);
printf("Number of bits in unsigned int = %zu\n", sizeof(unsigned int) * CHAR_BIT);
printf("Number of bits in long = %zu\n", sizeof(long) * CHAR_BIT);
printf("Number of bits in unsigned long = %zu\n", sizeof(unsigned long) * CHAR_BIT);
printf("Number of bits in float = %zu\n", sizeof(float) * CHAR_BIT);
printf("Number of bits in double = %zu\n", sizeof(double) * CHAR_BIT);
printf("Number of bits in long double = %zu\n", sizeof(long double) * CHAR_BIT);
And that can be reduced with a macro (though macros aren't the best, they are useful for repetitive code):
#define PRINT_BITS_IN_TYPE(type) \
printf("Number of bits in " #type " = %zu\n", sizeof(type) * CHAR_BIT)
PRINT_BITS_IN_TYPE(char);
PRINT_BITS_IN_TYPE(unsigned char);
PRINT_BITS_IN_TYPE(int);
PRINT_BITS_IN_TYPE(unsigned int);
PRINT_BITS_IN_TYPE(long);
PRINT_BITS_IN_TYPE(unsigned long);
PRINT_BITS_IN_TYPE(float);
PRINT_BITS_IN_TYPE(double);
PRINT_BITS_IN_TYPE(long double);
This is because the unsigned char is promoted to an int (in normal C implementations), so an int is passed to printf for the specifier %c. However, %c expects an unsigned int, so the types do not match, and the C standard does not define the behavior.
you can perform the following methods:
1) try using C11(standard version).
2) try using %zu.

How multiply with 12 decimals in C?

I'm trying to have precision of 12 decimals in C. I don't know if there's an easier solution. But at least that code works. Now I'm just trying to save the result in a "long double" but "strtold()" is not working
char* multiply12Decimals(float n1, float n2)
{
long n1Digits;
sscanf(doubleToVoidPointerInNewMemoryLocation(n1*1000000), "%ld", &n1Digits);
printf("n1Digits: %ld\n", n1Digits);
long n2Digits;
sscanf(doubleToVoidPointerInNewMemoryLocation(n2*1000000), "%ld", &n2Digits);
printf("n2Digits: %ld\n", n2Digits);
long long mult = (long long) n1Digits*n2Digits;
printf("mult: %lld\n", mult);
char *charNum = malloc(30*sizeof(char));
sprintf (charNum, "0.%012lld\n", mult);
printf("result: %s\n", charNum);
return charNum;
}
printf("%.12lf",num); solves the problem.
Multiply two double and print it like this. No need to use long.

Problem with big numbers in C

why should a code like this should provide a so high result when I give it the number 4293974227 (or higher)
int main (int argc, char *argv[])
{
unsigned long long int i;
unsigned long long int z = atoi(argv[1]);
unsigned long long int tmp1 = z;
unsigned long long int *numbers = malloc (sizeof (unsigned long long int) * 1000);
for (i=0; tmp1<=tmp1+1000; i++, tmp1++) {
numbers[i] = tmp1;
printf("\n%llu - %llu", numbers[i], tmp1);
}
}
Result should start with the provided number but starts like this:
18446744073708558547 - 18446744073708558547
18446744073708558548 - 18446744073708558548
18446744073708558549 - 18446744073708558549
18446744073708558550 - 18446744073708558550
18446744073708558551 - 18446744073708558551
ecc...
What's this crap??
Thanks!
atoi() returns int. If you need larger numbers, try strtol(), strtoll(), or their relatives.
atoi() returns (int), and can't deal with (long long). Try atoll(), or failing that atol() (the former is preferred).
You are printing signed integers as unsigned.

Resources