While assigning value to a unsigned long long variable in C, value of variable is not getting assigned properly. The code is:
#include <stdio.h>
int main()
{
unsigned long long x;
printf("%d\n\n",sizeof(x));
x=0xAAAAAAAAAAAAAAAAULL;
printf("%u\n\n",x);
printf("%ld\n\n",x);
return 0;
}
Rightmost 32 bits of the variable are being ignored. Can someone please tell me how to do this correctly.
Print unsigned long long with %llu.
Use llu or Lu format specifier for printf if you want to print unsigned long long. The format specifier depends on the compiler.
The assignment occurs correctly. However, the program is not displaying the value correctly.
printf("%Lu\n\n",x);
or
printf("%llu\n\n",x);
or maybe even
printf("%LLu\n\n",x);
depending on the compiler and specific runtime library.
You need to change the printfs to print properly.
#include <stdio.h>
int main()
{
unsigned long long x;
printf("%d\n\n",sizeof(x));
x=0xAAAAAAAAAAAAAAAAULL;
printf("%u\n\n",x); // not work
printf("%llu\n\n",x); // works
printf("%016llx\n\n",x); // bonus check
return 0;
}
Related
Function sqrtl doesn't work here, also the printf of long double prints f for all given numbers:
#include <conf.h>
#include <kernel.h>
#include <math.h>
#include <float.h>
long double sqrtn;
unsigned long int n;
void xmain() {
unsigned long int n;
printf("Enter unsigned long integer:\n");
scanf("%lu", &n);
sqrtn = sqrtl(long double)n);
printf("\nsqrtn=%Lf\n", sqrtn);
} /* main */
I downloaded the Xinu source code for x86 from https://xinu.cs.purdue.edu/files/Xinu-code-Galileo.tar.gz .
Looking at the implementation for printf (lib/printf.c lib/doprnt.c), as far as I can tell it simply doesn't support length modifiers. That means that, for example, this:
long int n = 42;
printf("%ld\n", n);
wouldn't work. I suggest trying that on your system.
This is not a conforming C implementation (and it's probably not intended to be).
It does appear to support most of the standard conversion specifiers ("%d", "%u", "%x", "%f", etc.).
If you want to print a long double value, I think the best you can do is either convert it to double and use "%f" (which could lose range and/or precision) or write your own code to convert a long double value to a string. (Or run you code on a different system).
Disclaimer: I haven't tried this, I've only examined the source code, and only for the x86 version of the system.
I was worried about long double won't print.
i wrote a small test and found out that my MAC wanted to have %Lf or %Le.
it seems that capital L must be used.
I am trying to convert a float to an IEEE-754 Hex representation. The following code works on my Mac.
#include <stdio.h>
#include <stdlib.h>
union Data {
int i;
float f;
};
int main() {
float var = 502.7;
union Data value;
value.f = var;
printf("%08X\n", value.i);
return 0;
}
This is giving me the expected result of 43FB599A.
When I run this code on an ATmega64a I am getting 0000599A not 04A2599A as originally posted which was a mistake.
The first two bytes are not expected but the final two bytes seem correct?
Any ideas?
As mentioned in the accepted answer the I was assuming that int was 4 bytes. I was writing the code on my mac and sending it to someone that was downloading it to an 8-bit ATmega64a. On the ATmega64a int is 2 bytes, not 4. I changed int to unsigned long which is 4 bytes on the ATmega64a.
In addition, I had to add a length sub-specifier of l to the format given to printf. This is because when given a specifier of x, printf uses a type of unsigned int to interpret the corresponding argument. Adding the length sub-specifier of l tells printf to use the type of unsigned long to interpret the corresponding argument.
Using only the length sub-specifier of l and not changing the variable i to unsigned long was causing printf to grab some extra bytes and output 04A2599A as originally posted. I, of course, needed to change the type of i to unsigned long as well as use the length sub-specifier of l.
http://www.cplusplus.com/reference/cstdio/printf/
This processor is an 8 bit one which mean size of int is most likely 2 byte not 4 as your code assume.
Try to use uint32_t rather then int if you can.
Please consider the below program and observe the output.
#include <stdio.h>
int main()
{
unsigned long long val ;
val =144111444250;
printf ("%llu\n", val);
printf ("%u %llu\n",val, val);
return 0;
}
output:
144111444250
33 10211385600662044705
Using %llu in first printf gives correct result but using %llu in second printf is giving wrong result.
This is undefined behaviour: printf expects an unsigned int for %u but you provide an unsigned long long int, whatever happens after that is up to the whimsy of the compiler.
The format specifiers for printf and scanf not only indicate how something should be printed/scanned, but also what kind of arguments to expect. If you lie you can't expect the results to be reasonable.
Basically I am trying to convert hex strings into unsigned long long values using strtoull. Here's the simple code
#include <stdio.h>
#include <string.h>
int main ()
{
unsigned long long val =0;
//printf("sizeof(unsigned long long)=%d\n", sizeof(unsigned long long));
val = strtoull("0x8004298c42ULL",NULL,16);
printf("%llx\n", val);
if ( val == 0x8004298c42ULL)
{
printf("Success\n");
}
return 0;
}
I expect val to print 8004298c42 but it prints 4298c42. The 8 is being chopped off. I tried without the 0x and without the ULL too. But still the same result. Just to make sure that I am not missing out on some trivial printf format specifier thing, I even checked the contents of val. Still no use( ie Success was not printed )
I think I am missing out something trivial but don't know what!
The function strtoull() is declared in <stdlib.h>, not <string.h>, so the compiler thinks it returns an int, not an unsigned long long.
Cure: make sure that all functions are declared before they are used. If you use gcc, then you should consider some combination of -Wall, -Wextra, -Wstrict-prototypes, -Wmissing-prototypes, -Wold-style-declaration, -Wold-style-definition and -Werror.
I have a given code, in my opinion there is something wrong with that code:
I compile under XINU.
The next variables are relevant :
unsigned long ularray[];
int num;
char str[100];
There is a function returns int:
int func(int i)
{
return ularray[i];
}
now the code is like this:
num = func(i);
sprintf(str, "number = %lu\n", num);
printf(str);
The problem is I get big numbers while printing with %lu, which is not correct.
If i change the %lu to %d, i get the correct number.
For example: with %lu i get 27654342, while with %d i get 26, the latter is correct;
The variables are given, the declaration of the function is given, i write the body but it must return int;
My questions are:
I'm not familiar with 'sprintf' maybe the problem is there?
I assigned unsigned long to int and then print the int with %lu, is That correct?
How can i fix the problem?
Thanks in advance.
Thanks everyone for answering.
I just want to mention I'm working under XINU, well i changed the order of the compilation of the files and what you know... its working and showing same numbers on %lu and %d.
I'm well aware that assigning 'unsigned long' to int and then printing with %lu is incorrect coding and may result loss of data.
But as i said, the code is given, i couldn't change the variables and the printing command.
I had no errors or warnings btw.
I have no idea why changing the compilation order fixed the problem, if someone have an idea you are more then welcome to share.
I want to thank all of you who tried to help me.
I assigned unsigned long to int and then print the int with %lu, is That correct?
No, it isn't correct at all. Think about it a bit! Printf tries to access the memory represented by the variables you pass in and in your case, unsigned long is represented on more bits than int, hence when printf is told to print an unsigned int, it'll read past your actual int and read some other memory which is probably garbage, hence the random numbers. If printf had a prototype mentioning an unsigned long exactly, the compiler could perform an implicit cast and fill the rest of the unwanted memory with zeroes, but since it's not the case, you have to do either one of these solutions:
One, explicit cast your variable:
printf("%lu", (unsigned long)i);
Two, use the correct format specifier:
printf("%d", i);
Also, there are problems with assigning an unsigned long to an int - if the long contains a too big number, then it won't fit into the int and get truncated.
1) the misunderstanding is format specifiers in general
2) num is an int -- therefore, %d is correct when an int is what you want to print.
3) ideally
int func(int i) would be unsigned long func(size_t i)
and int num would be unsigned long num
and sprintf(str, "number = %d\n", num); would be sprintf(str, "number = %lu\n", num);
that way, there would be no narrowing and no conversions -- the type/values would be correctly preserved throughout execution.
and to be pedantic, printf should be printf("%s", str);
if you turn your warning levels way up, your compiler will warn you of some of these things. i have been programming for a long time, and i still leave the warning level obnoxiously high (by some people's standards).
If you have an int, use %d (or %u for unsigned int). If you have a long, use %ld (or %lu for unsigned long).
If you tell printf that you're giving it a long but only pass an int, you'll print random garbage. (Technically that would be undefined behavior.)
It doesn't matter if that int somehow "came from" a long. Once you've assigned it to something shorter, the extra bytes are lost. You only have a int left.
I assigned unsigned long to int and then print the int with %lu, is That correct?
No, and I suggest not casting to int first or else simply using int as the array type. It seems senseless to store a much larger representation and only use a smaller one. Either way, the sprint results will always be off until you properly pair the type (technically the encoding) of the variable with the format's conversion specifier. This means that if you pass an unsigned long, use %ul, if it's an int, use either %i or %d (the difference is that %d is always base-10, %i can take additional specifiers to print in other bases.
How can I fix the problem?
Change the return of your func and the encoding of num to unsigned long
unsigned long ularray[];
unsigned long num;
char str[100];
unsigned long func(int i)
{
return ularray[i];
}