Printing an unsigned long in hex in c - c

I have troubles with printing a big 16 digits hex number in c
unsigned long long j = 0x89ABCDEF12893456;
printf("0x%lx\n", j); //prints: 0x12893456
printf("%#lx", j); //prints: 0x12893456
is there a way to print the whole number?

As per the C standard, C11 7.21.6 Formatted input/output functions /7 which discusses length modifiers:
ll (ell-ell): Specifies that a following d, i, o, u, x, or X conversion specifier applies to a long long int or unsigned long long int argument; or that a following n conversion specifier applies to a pointer to a long long int argument.
A single l specifies a long or unsigned long. Hence %llx or %#llx is the format specifier you want, possibly with an output length and zero padding as well, if you want the numbers to line up (such as "0x%016llx").

That should do it.
#include <stdio.h>
int main () {
unsigned long long j = 0x89ABCDEF12893456;
printf("%#llx", j);
return 0;
}

Related

Why does unsigned short (0xffff) print 65,535 and unsigned int (0xffffffff) print -1 in C?

I think the title explains pretty well what I'm asking so here is my code.
#include <stdio.h>
unsigned short u_short = 0xffff;
unsigned int u_int = 0xffffffff;
int main(){
printf("unsigned short = %d\n", u_short);
printf("unsigned int = %d\n", u_int);
return 0;
}
Here is my printout.
printout picture
printf("unsigned int = %d\n", u_int); is undefined behavior (UB) when u_int is out of the positive int range. Do not used "%d" to print unsigned.
Use printf("unsigned int = %u\n", u_int);
This is likely what happened in your C implementation:
In printf("unsigned short = %d\n", u_short);, the unsigned short value 65,535 is automatically converted to an int with the same value.1,2
The int value 65,535 is passed to printf, which formats it as “65535” due to the %d conversion specification.
In printf("unsigned int = %d\n", u_int);, the unsigned int value 4,294,967,295 is passed to printf; it is not converted to an int. As an unsigned int, 4,294,967,295 is represented with 32 one bits.
Because of the %d conversion specification, printf seeks an int value that was passed as an argument. For this, it finds the bits passed for your unsigned int, because an unsigned int and an int are passed in the same place in your C implementation, so the printf looking for an int finds the bits in the same place the calling routine put the unsigned int bits.3
When interpreted as an int type, these bits, 32 ones, represent the value −1.3 Given the −1 value, printf formats it as “-1” due to the %d conversion specification.
Footnotes
1 In many places in expressions, including arguments corresponding to ... of a function declaration, values of types narrower than int are automatically promoted to int, as part of the integer promotions.
2 A C implementation could have an unsigned short as wide as an int, in which case this conversion would not occur. That is rare these days.
3 This is a description of what likely happened in your C implementation. The behavior is not defined by the C standard and may vary in other C implementations or even in different programs in your C implementation.
printf has some anomalies due to the usual argument promotions. In particular, arguments of type char and short are promoted to int when passing them to printf. Usually this is fine, but sometimes it results in surprises like these. What you get when you promote an unsigned 16-bit 0xffff to 32 bits is not 0xffffffff.
printf has some relatively little-known and relatively rarely-used modifiers to, in effect, undo those promotions and print char and short arguments as what they "really were". So you'll see more-consistent results if you tell printf that you were actually passing a short, like this:
printf("unsigned short = %hd\n", u_short);
printf("unsigned int = %d\n", u_int);
Now printf knows that the argument in the first call was really a short, so it treats it as such. On my machine, this now prints
unsigned short = -1
unsigned int = -1
(Now, with that said, it's arguably a bad idea to print unsigned integers with %d, as the other answers and comments have explained.)

Clarification on various format specifiers in C program

I am not understanding what is major difference between %p,%u,%x,%d, except that %x shows hexadecimal,%u is used for unsigned integer and that %d is for any integer. I am very much confused after I took a integer variable and printed its address and its value (positive integer) separately, then irrespective of whatever format specifier I use, it was correctly printing the output (except of the difference in hexadecimal and decimal number system). So what is a major difference?
And if there is not much difference then which format specifiers are preferable for printing what type of variables?
Another doubt is that: Whether pointer of all multiplicity (I mean int *p; int **p; int ***p; etc.) occupy the same size (which is the size needed to store a valid address in the machine)? If not, then what is the size of these pointers?
Thanks for your help.
The %u, %x, %d, and %p format specifiers are used as follows:
%u: expects an unsigned int as a parameter and prints it in decimal format.
%x: expects an unsigned int as a parameter and prints it in hexadecimal format.
%d: expects an int as a parameter and prints it in decimal format.
%p: expects a void * as a parameter and prints it in an implementation defined way (typically as a hexadecimal number)
Additionally, %u, %x, %d can be prefixed with a length modifier:
l: denotes a long int or unsigned long int
ll: denotes a long long int or unsigned long long int
h: denotes a short int or unsigned short int
hh: denotes a signed char or unsigned char
Regarding pointer sizes, int *, int **, int ***, etc. are not required to be the same size, although on most implementations they will be.
With format specifiers, you tell the computer how to interpret the given variable/data.
A quick demo:
#include <stdio.h>
int main(void)
{
int x = -5;
printf("x value as int: [%d]\n", x);
printf("x value as unsigned int: [%u]\n", x);
printf("x value as hexadecimal: [%x]\n", x);
printf("x value as pointer: [%p]\n", x);
return 0;
}
Output:
x value as int: [-5]
x value as unsigned int: [4294967291]
x value as hexadecimal: [fffffffb]
x value as pointer: [0xfffffffb]
It's the same value given every time, i.e. x = -5.
We see the exact representation when given the right format specifier (the first case).
In second case we see a very big number. The answer to "Why" is a bit long to explain here, but you should look up how negative integers are represented in 2's complement system.
In the third case we see the hexadecimal representation of the number 4294967291. Hexadecimal numbers are usually shown with 0x at the beginning but %x doesn't do that.
The last one just shows how would the variable x seem if it were an address in the memory, again in hexadecimal format of course.

long long division in c

am trying to pass along a "long long" number, the problem is when I try to divise this number by 10 , the answer is incorrect ..
#include <stdio.h>
int main(void)
{
int n = 0 ;
long long s = 4111111111111111;
n = s % 10 ;
printf("n after modulos %i\n",n );
s = s / 10 ;
printf("this is s after division %llo \n",s );
return 0;
}
Output :
n after modulos 1
this is s after division 13536350357330707
printf("this is s after division %llo \n",s );
^ (this prints (correct)value in octal representation)
Use specifier %lld (to get value in decimal ) .
man 3 printf
o, u, x, X
The unsigned int argument is converted to unsigned octal (o), unsigned decimal (u), or unsigned hexadecimal (x and X) notation. The letters abcdef are used for x conversions; the letters ABCDEF are
used for X conversions. The precision, if any, gives the minimum number of digits that must appear; if the converted value requires fewer digits, it is padded on the left with zeros. The default
precision is 1. When 0 is printed with an explicit precision 0, the output is empty.
and some more on manual
man 3p printf
ll (ell-ell)
Specifies that a following d, i, o, u, x, or X conversion specifier applies to a long long or unsigned long long argument; or that a following n conversion specifier applies to a pointer to a long
long argument.
To print a long long, you should use %lld not %llo
The %llo format is used for representing a long long value in octal.

when storing a large positive integer it is converting to different negative number

When i storing a large positive integer in unsigned long int in c, then it unknowingly converting to negative number.
for example
a=2075000020, b=100000000,here a+b=-2119967266.
Please help me understand.
You cannot have been printing an unsigned integer, because it has printed a sign. Even if you declare the variable as unsigned, once it is on the stack for printf() to use, it is interpreted as a binary value to be used as specified by the format in printf().
Note the difference between these, and the results. In the the third example, you can see that bit 31 is set, which is the sign bit for signed long int.
#include <stdio.h>
#include <string.h>
int main () {
unsigned long int a=2075000020, b=100000000, c;
c = a + b;
printf ("Signed %ld\n", c);
printf ("Unsigned %lu\n", c);
printf ("Hexadecimal 0x%lX\n", c);
return 0;
}
Program output:
Signed -2119967276
Unsigned 2175000020
Hexadecimal 0x81A3DDD4

C - copy characters ASCII value to 64bits integer

As we all know, each printable character has its ascii value. I'm trying to 8 characters' ascii value to 64 bits integer, but it only copies 32 bits.
char * ch = "AAAABBBB";
unsigned long int i;
//copy charater's ascii to 64 bits int
memcpy(&i, ch, 8);
printf("integer hold: 0x%x\n", i);
Is there something wrong with this code?
Output I expect was:
integer hold: 0x4141414142424242
but output was:
integer hold: 0x41414141
If unsigned long is indeed a 64-bit type (you can output sizeof(unsigned long) to check this), you still need to use %lx format string to print it.
If unsigned long is 32 bits, you'll probably have to resort to unsigned long long and use the %llx format string.
From C11 7.20.6.1 The fprintf function:
o,u,x,X The unsigned int argument is converted to unsigned octal (o), unsigned decimal (u), or unsigned hexadecimal notation (x or X) in the style dddd; the letters abcdef are used for x conversion and the letters ABCDEF for X conversion. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded with leading zeros. The default precision is 1. The result of converting a zero value with a precision of zero is no characters.
l (ell): Specifies that a following d, i, o, u, x, or X conversion specifier applies to a long int or unsigned long int argument.
ll (ell-ell): Specifies that a following d, i, o, u, x, or X conversion specifier applies to a long long int or unsigned long long int argument.
long versus long long.
In VC++ the long datatype is still only 32 bits.
And of course, the printf format %x is used for int which is 32 bits on most platforms. You want %llx (or possibly %lx if your long already is 64 bits).
%x is used to print unsigned int value & its 32 bit that's why you are getting such result.
%d %i Decimal signed integer.
%o Octal integer.
%x %X Hex integer.
%u Unsigned integer.
%c Character.
%s String.
%f double
%e %E double.
%g %G double.
%p pointer.
& if you want to print the remaining data try ...
int *p;
p=(char *)(&i)+4;
printf("integer hold: 0x%x\n", i);
printf("integer hold: 0x%x\n",*p);

Resources