float output format yields weird value [duplicate] - c

This question already has answers here:
Displaying floating point variable as a hex integer screws up neighbouring integer
(2 answers)
Closed 8 years ago.
OK:
I found that this is a dupe question
For my answer to this question, I tested what would happen if I passed a float to printf, and have it printed out as a hexadecimal value.
The code I used was simply this:
int main()
{
float i = 12.2;
printf("%x == %f\n", i, i);
return 0;
}
The result was somewhat surprizing, to say the least:
60000000 == 26815622268991053043690768862555225929794561970930945383754133458631904088629457662404735694345936594619420127195201411004744101710347755649498829446709248.000000
Now that couldn't be quite true, I do think. If I switch the order of the format string to "%f == %x\n", the float shows up well (12.200000).
Now this intrigued me somewhat. So I did some more experimenting
printf("%f == %x == %f\n", i, i, i);
revealed to me that the %f format fails after the %x has been used. So I tried:
printf("%f == %x == %f\n", 12.2, i, 12.2);
Which had me scratching my noodle even more:
12.200000 == 60000000 == 190359837254612272720121546180914982603183590679420528733621571728996711854558612668142684377801318191569131534073063745617380878171517108433746379972393615159806611654135195336789983232.000000
And, before you ask:
printf("%f == %x == %f\n", 12.2f, i, 12.2f);
yields:
12.200000 == 60000000 == 26815622268991053043690768862555225929794561970930945383754133458631904088629457662404735694345936594619420127195201411004744101710347755649498829446709248.000000
When I print printf("%f\n", i) either before or after the statement(s) I posted above, the output is as I'd expect it to be.
Does anyone have any idea what is going on here?

Your program's behavior is undefined. Wrong conversion specifier invokes undefined behavior.

The %x format is for integers, not floating point. To print a float in hex format, use %a. To print the raw bytes of a float (or other arbitrary object) in hex, which is what I'm guessing you really want, you have to use a union:
union {
float f;
unsigned int i;
} u;
u.f = 1.2;
printf("%x", u.i);
or memcpy the bytes from the float to an int and then printf the int.
Or you can cheat and use *(int *)&some_float

Related

Using the int type in the printf function does not add the same value as the float type [duplicate]

This question already has answers here:
What happens to a float variable when %d is used in a printf?
(4 answers)
C printf using %d and %f
(4 answers)
c-behaviour of printf("%d", <double>) [duplicate]
(1 answer)
Why is this code printing 0?
(5 answers)
Closed 6 months ago.
When I use the following code, the output result is 0 when adding the sum in the printf function, but when I add the printf function it should be printf("test: %d", c/ 2);The output is 1,
Why?
int main() {
float a = 1.5;
int b = 2;
int c = a + b;
printf("test: %d", (a+b)/ 2);
}
Since you assign the result of a + b to an int variable, its result will be truncated.
So while the result of 1.5 + 2 is 3.5, the result assigned to c will be the integer 3.
And since both c and 2 are int values the result of c / 2 will be an int which will be truncated. So the result of 3 / 2 will simply be 1.
With the edit and the new print:
printf("test: %d", (a+b)/ 2);
Because one of the values involved in the expression a + b if a float, the result will be a float. And because of that the result of the division will also be a float.
The result of (a + b) / 2 will be a float. But since it's passed as an argument to a variable-argument function like printf it will be promoted to a double. So your statement is essentially equivalent to:
printf("test: %d", (double)((a+b)/ 2));
Now for the big problem: The %d format specifier expects an int value. Mismatching format specifier and argument type leads to undefined behavior.

7%9 is showing different answers when using integer and float format specifiers. Why is it so?

# include<stdio.h>
int main() {
printf("%d \n", 7%9); //integer result
printf("%f", 7%9); //float result
return 0;
}
Above is the code I used to calculate the value of 7%9. I wanted to see both the integral and the float result. But, the values appearing here are different.
printf("%d \n", 7%9); //integer result
printf("%f", 7%9); //float result
Although the comments and the format specifiers indicate your intent, the compiler sees the integer calculation and passes an integer value to printf().
In the 2nd line, you've effectively written:
printf( "%f", 7 );
That is obviously incorrect.
If you wanted to see lots of zeros, you could cast the value to match what you've written as the format specifier:
printf( "%f", (float)( 7 % 9 ) );

why my printf is always repeating the first output [duplicate]

This question already has answers here:
Printing int as float in C
(7 answers)
Closed 1 year ago.
#include <stdio.h>
#include <math.h>
int main(void)
{
float a = 16777215;
int b = pow(2, 26);
float c = 22345678;
printf("%f\n", a);
printf("%f\n", b);
puts("---------------");
printf("%f\n", c);
printf("%f\n", b);
return 0;
}
output:
16777215.000000
16777215.000000
---------------
22345678.000000
22345678.000000
why the former printf output can have influence to the subsequent printf output?
b isn't a float. Try %i for integer or %d for decimal.
#include <stdio.h>
#include <math.h>
int main(void)
{
float a = 16777215;
int b = pow(2, 26);
float c = 22345678;
printf("%f\n", a);
printf("%i\n", b);
puts("---------------");
printf("%f\n", c);
printf("%i\n", b);
return 0;
}
You need to match the type or strange things can happen:
printf("%d\n", b);
Compiling the original code with clang gives helpful warnings:
pow.c:10:20: warning: format specifies type 'double' but the argument has type 'int' [-Wformat]
printf("%f\n", b);
~~ ^
%d
pow.c:13:20: warning: format specifies type 'double' but the argument has type 'int' [-Wformat]
printf("%f\n", b);
~~ ^
%d
varargs functions like printf have a hard time pinning down their type requirements, it's up to compilers like clang to go the extra mile and show hints like this. You'll need to be extra careful when calling functions of that sort and be sure you're doing it precisely as documented.
As to how this ended up happening, it's not clear, but it doesn't have to be. Undefined behaviour is just that: Anything can happen. It could print the same thing. It could work. It could crash. There doesn't have to be an explanation.
Undefined behavior as you try to print integer with %f
Try
printf("%d\n", b);
To answer your specific question, my guess is that, at the assembly level, if the conversion is not correctly indicated, it will jump to ret, using the value previously stored in eax register.

Why am I getting a strange number in this code?

I want to write a C program that evaluates the factorials of the integers from 1 to 5 and print them in a tabular format. However, I keep getting a strange number over everything. Here's the code:
#include <stdio.h>
int main()
{
int factorial;
printf("X\t Factorial of X\n");
for(int x=1; x<=5; x++)
{
factorial = 1;
for (int j=1; j<=x; j++)
{
factorial *=j;
}
printf("%d\t %d\n", &x, &factorial);
}
return 0;
}
Here's the result of this code:
X Factorial of X
6356768 6356772
6356768 6356772
6356768 6356772
6356768 6356772
6356768 6356772
What's wrong with my code? The result should be like this:
X Factorial of X
1 1
2 2
3 6
4 24
5 120
Remove & which stands for address of. You are printing address of the variable, not its value.
printf("%d\t %d\n", x, factorial);
When using printf (and related output functions), the %d format specifier expects an int as the corresponding argument. In your printf("%d\t %d\n", &x, &factorial); you are passing the addresses of the x and factorial variables.
So, just remove the two & (address of) operators: printf("%d\t %d\n", x, factorial);!
You are possibly being confused by the fact that, for scanf (and other input functions), the %d specifier requires a pointer to its target variable.
printf("%d\t %d\n", &x, &factorial);
&x and &factorial are addresses of those variables, not the variables themself. Omit the &.
In the statement printf("%d\t %d\n", &x, &factorial); you have used '&' which prints the address of that element.
Unlike scanf, printf() with format %d requires integer values, not addresses (&x is the address containing an integer, so a pointer to integer which type is int *). The correct expression is
printf("%d\t %d\n", x, factorial);
Why was the previous expression wrong?
With printf("%d\t %d\n", &x, &factorial); you are asking to printf to print the decimal representations of the addresses of x and factorial respectively.
For this reason it is not surprising that the values that used to be printed, 6356768 and 6356772:
Are big numbers, multiples of 4 (because they address integers, that have a size 4 bytes, and in 32 bits architectures like yours are aligned to memory locations multiples of 4)
They are memory locations, and their addresses do not vary even if their contents are changed
You can find printf documentation here.

C programming about "double" multiplication

I'm currently learning the C language and I'm having trouble in the double multiplication topic.
I need to to print the original value and then the 2*value of the double.
double num = 34.39;
printf("Original value = %d, 2x original value = %d", num, num*2);
How do I make it so that the 2x value will be really 2x the original value?
Your multiplication is not the problem.
Your printf format string is. %d is not for floating-point values, but for integers, so you're seeing nonsense resulting from your broken contract with the compiler.
double num = 34.39;
printf("Original value = %lf, 2x original value = %lf", num, num*2);
%d - for int
You must use the "%f" for printf

Resources