I have the hex value 0x5a800000000b and I'm trying to get a printf statement in C to print it to the console.
So far (because I'm useless in C) I'm able to get the 'b' to print, using the syntax:
printf("Hex value%x\n", value);
The value is stored in an integer type U32, but after trying all different combinations of %llx, %lx, I just keep getting compiler warnings.
I'm guessing that I'm getting the printf syntax wrong, but I can't seem to find the right % option, can someone help me out?
Thanks
It's not a problem with the printf.
The problem is that a 32 bits variable cannot hold the value 0x5a800000000b. 32 bits can hold only 8 hex digits: 0x0000000b. Hence the b on output.
To store such a large value, you should use a 64 bits variable.
long long value = 0x5a800000000bLL
Note also the double L at the end. It tells the compiler that the constant is also a long long.
Then you can use %llx in the printf format string.
There are some pre-defined macro for these types:
#include <inttypes.h>
int64_t PRId64. PRIi64
int32_t PRId32, PRIi32
int16_t PRId16, PRIi16
int8_t PRId8, PRIi8
For example:
printf("%"PRId32"\n", my32Int);
The value 0x5a800000000b is more that 32 bits, so you have to use a long.
long value = 0x5a800000000bl;
printf("Hex value%lx\n", value);
Note that hex constant should end in l,.
Related
This question already has answers here:
Using %f to print an integer variable
(6 answers)
Closed 3 years ago.
I want to know why sizeof doesn't work with different types of format specifiers.
I know that sizeof is usually used with the %zu format specifier, but I want to know for my own knowledge what happens behind and why it prints nan when I use it with %f or a long number when used with %lf
int a = 0;
long long d = 1000000000000;
int s = a + d;
printf("%d\n", sizeof(a + d)); // prints normal size of expression
printf("%lf\n", sizeof(s)); // prints big number
printf("%f", sizeof(d)); // prints nan
sizeof evaluates to a value of type size_t. The proper specifier for size_t in C99 is %zu. You can use %u on systems where size_t and unsigned int are the same type or at least have the same size and representation. On 64-bit systems, size_t values have 64 bits and therefore are larger than 32-bit ints. On 64-bit linux and OS/X, this type is defined as unsigned long and on 64-bit Windows as unsigned long long, hence using %lu or %llu on these systems is fine too.
Passing a size_t for an incompatible conversion specification has undefined behavior:
the program could crash (and it probably will if you use %s)
the program could display the expected value (as it might for %d)
the program could produce weird output such as nan for %f or something else...
The reason for this is integers and floating point values are passed in different ways to printf and they have a different representation. Passing an integer where printf expects a double will let printf retrieve the floating point value from registers or memory locations that have random contents. In your case, the floating point register just happens to contain a nan value, but it might contain a different value elsewhere in the program or at a later time, nothing can be expected, the behavior is undefined.
Some legacy systems do not support %zu, notably C runtimes by Microsoft. On these systems, you can use %u or %lu and use a cast to convert the size_t to an unsigned or an unsigned long:
int a = 0;
long long d = 1000000000000;
int s = a + d;
printf("%u\n", (unsigned)sizeof(a + d)); // should print 8
printf("%lu\n", (unsigned long)sizeof(s)); // should print 4
printf("%llu\n", (unsigned long long)sizeof(d)); // prints 4 or 8 depending on the system
I want to know for my own knowledge what happens behind and why it prints nan when I use it with %f or a long number when used with %lf
Several reasons.
First of all, printf doesn't know the types of the additional arguments you actually pass to it. It's relying on the format string to tell it the number and types of additional arguments to expect. If you pass a size_t as an additional argument, but tell printf to expect a float, then printf will interpret the bit pattern of the additional argument as a float, not a size_t. Integer and floating point types have radically different representations, so you'll get values you don't expect (including NaN).
Secondly, different types have different sizes. If you pass a 16-bit short as an argument, but tell printf to expect a 64-bit double with %f, then printf is going to look at the extra bytes immediately following that argument. It's not guaranteed that size_t and double have the same sizes, so printf may either be ignoring part of the actual value, or using bytes from memory that isn't part of the value.
Finally, it depends on how arguments are being passed. Some architectures use registers to pass arguments (at least for the first few arguments) rather than the stack, and different registers are used for floats vs. integers, so if you pass an integer and tell it to expect a double with %f, printf may look in the wrong place altogether and print something completely random.
printf is not smart. It relies on you to use the correct conversion specifier for the type of the argument you want to pass.
I am currently working on a project in C and I am running into some issues when I am trying to concatenate some binary numbers.
uint64_t IMM = vmicxtFetch4Byte(processor, thisPC+2);
uint64_t shiftedInstr = ((uint64_t) instr16) << 32;
uint64_t instr48 = IMM | shiftedInstr;
printf("Instr16: %x IMM: %lx Instr64: %lx\n", instr16, (unsigned long) IMM, (unsigned long) instr48);
Now the output I get for the Immediate value (IMM) and the initial instruction (instr16) are correct but the OR'd result doesn't seem to be giving me what I want. I expect 068200000040 but i get
Instr16: 682 IMM: 40 Instr64: 40
I have done this sort of binary math a lot and for some reason this is tripping me up. Any thoughts would be appreciated!
This is a problem with output, not with the computation. You cast the converted value of instr48 to unsigned long, which appears to be a 32-bit type on your system. The most significant portion of instr48 gets "sliced off", so you get the value that consists of only the least significant part.
You should cast it to unsigned long long instead, and use %llu format specifier.
To get "068200000040" from instr48 code needs
Leading 0 in print specifier
Print width of 12.
Matching specifier sequence which for uint64_t is found in #include <inttypes.h>
#include <inttypes.h>
printf("Instr64: %012" PRIx64 "\n", instr48);
Uint64_t a;
Uint32 b;
a= clock_cycles();
b= uint32((a*1000000)/(SYSPAGE_ENTRY(qtime)->cycles_per_sec));
printf("RECEIVE from Time in microseconds: %ld\n", b);
I created the variable and taking the timestamp and converting that into uint32 as shown in the above code.
If I print the b value then I am getting negative value!!
What's wrong in doing like above ??
Your b is larger than 2^31. Printf format "%ld" indicates you are going to print a signed integer and printf interprets numbers with highest bit as negative integers. Use "%lu" instead of "%ld".
Also when looking at your code, the numeric value of a*1000000 is very probable to overflow over maximal possible value. In your case, I'd suggest to use another function to get microsecond time, for example gettimeofday and to store the result in a 64-bit integer.
I've stored a very large number in a float variable, but when I print it I want to only display the whole number part and nothing after the decimal point.
For numbers in the int or long range, I would do a casting but this hasn't helped me because the number I want to print is too long for int or long.
I've looked at this explanation: http://www.cprogramming.com/tutorial/printf-format-strings.html but I haven't succeeded in solving this.
this is my code and my attempt to do the casting:
double sum=552074001368;
long long_sum;
long_sum = (long)(sum); //int casting for double "add"
if(sum>=0) printf("=\n%ld\n",long_sum);
else printf("=\n%ld\n",-long_sum);
I don't want to use a specific precision like printf("%15f") because this variable fluctuates and is sometimes very short like 4 digits.
Use the precision modifier .0 and print the floor of the number:
printf("%.0f\n", floor(sum));
(Or the floor of the abs, if you want only the magnitude, as in your example code.)
I think what you're after is %.0f. For example:
#include <stdio.h>
int main(){
double x = 1234.567;
printf("%.0f", x);
return 0;
}
...prints:
1235
Why are you casting to long at all? Use the printf format specifiers to control what and how many characters are printed.
http://www.cplusplus.com/reference/clibrary/cstdio/printf/
Remember that both the width and the precision can be specified by a variable and doesn't have to be known at compile time:
printf("=\n%.*lf\n", 4, sum); // print 4 places behind the decimal point
int i;
i = 5;
// print only the whole number part of sum and output at least i characters,
// pad with leading spaces if number requires fewer than i characters
printf("=\n%*.*lf\n", i, 0, sum);
This line is problematic:
double sum=552074001368;
Since that is an integer literal, the compiler will first check if the number will fit in an int, then long, then long long. If it won't fit in long long I suspect you'll get either a compiler error or undefined behavior wrap-around, I'm not sure of which.
If your compiler supports long long, then the code will work and the number will be stored in a temporary long long (which will be optimized away). This long long is then stored inside a double.
Instead, write like this:
double sum=552074001368.0;
The .0 syntax gives you a double floating point literal without involving integer types at all.
double sum=552074001368LL;
long long long_sum;
long_sum = (long long)(sum);
if(sum>=0) printf("=\n%lld\n",long_sum);
else printf("=\n%lld\n",-long_sum);
i m trying to enter a five digit number greater than 32767 and i used "unsigned" while declaring int number, and when i m trying to print the same number it prints some arbitary negative number,
results get overflowed......
pls help me out
Without seeing your code, I am guessing you are using %d or %i in the printf statement. Use %u instead.
Print unsigned values using "%u" instead of "%d".
Until you show some of the code, I can't be sure of anything.
But AFAIK you shouldn't be able to print out a negative number if you're printing out an uint – even if it overflows, the integer will always hold a positive number, as far as C is concerned.
So there's something else wrong.
Use correct format specifier.
%d for int
%u for unsigned int.
Using incorrect format specifier in printf() may cause Undefined Behavior.
For example, the following code invokes Undefined Behavior(UB).
#include<stdio.h>
int main(void)
{
unsigned int z=Some_value; /*Some_value is an unsigned int */
printf("%d",z);
/*UB as format specifier for unsigned int is incorrect,it should be %u not %d*/
}
I guess int is 16bit on your machine/compiler.
Though I don't know what your platform is, I guess that long would solve your problem (it is 32bit or more on all platforms I know). Print it with %ld instead of %d.
Don't get tempted to use unsigned and %u, because they will just give you numbers up to 65536, and I guess that you want more.