Question about mixed scalar type operation

L

linq936

Hi,
I have this little test program:

#include <stdio.h>

int main(){
float f1 = 2.2;
double d1 = 3.3;
int j = f1 * d1;
int i = (int) f1 * d1;
int i2 = (int) (f1 * d1);
printf("%d, i=%d, j=%d, i2=%d\n", f1*d1, i, j, i2);
}

I use gcc on Linux to compile it, there is no warning and the result
is like this:

2066953011, i=1075644989, j=6, i2=7

I have several questions:

1. Why there is no warning in compiler when I assign the
multiplication of float and double to integer?

2. As for the result, I can understand how i2 comes from, but others
do not make sense to me.

Could you give me some pointer?
 
W

Walter Roberson

I have this little test program:
#include <stdio.h>
int main(){
float f1 = 2.2;
double d1 = 3.3;
int j = f1 * d1;
int i = (int) f1 * d1;
int i2 = (int) (f1 * d1);
printf("%d, i=%d, j=%d, i2=%d\n", f1*d1, i, j, i2);
}
I use gcc on Linux to compile it, there is no warning and the result
is like this:
2066953011, i=1075644989, j=6, i2=7
I have several questions:
1. Why there is no warning in compiler when I assign the
multiplication of float and double to integer?

It is not considered a syntactic or semantic error to do such
a multiplication and assignment -- the results are well defined.
The compiler is not required to return a warning for well defined
behaviour that -might- have been the result of the programmer having
overlooked something (or might have been perfectly intended.)

2. As for the result, I can understand how i2 comes from, but others
do not make sense to me.

In your printf() statement, f1*d1 is going to be a double, and you
attempt to print that double out using an integer format. If it
happens that on your machine that a double is "wider" than an
integer, the %d format will only use up some of the bytes of the double,
possibly leaving the other bytes from the double in a location to
be printed by the next format element along, i=%d . Once that has
happened, everything else gets shifted along from what you expect.
 
M

Martin Ambuhl

Hi,
I have this little test program:
#include <stdio.h>
int main(){
float f1 = 2.2;
double d1 = 3.3;
int j = f1 * d1;
This is exactly the same as the i2 case below
int i = (int) f1 * d1;
This is (int) 2.2 * 3.3 ->
2 * 3.3 ->
6.6
assigned to an int as 6
int i2 = (int) (f1 * d1);
This is (int) (2.2 * 3.3) =>
(int) (7.26) ->
7
printf("%d, i=%d, j=%d, i2=%d\n", f1*d1, i, j, i2);
^^
This is an error. f1*d1 is a floating point value.
%d is a specifier for signed ints.
Unless a double and an int have exactly the same size,
you have hopelessly munged the arguments to printf.

Unless you are using a C99 compiler, you need to return a
value here, e.g.
return 0;
I use gcc on Linux to compile it, there is no warning and the result
is like this:
2066953011, i=1075644989, j=6, i2=7

After you change the erroneous "%d" to "%g", the output should look like:
7.26, i=6, j=7, i2=7


I have several questions:
1. Why there is no warning in compiler when I assign the
multiplication of float and double to integer?

Because there is absolutely nothing wrong with doing so, and there is
nothing to warn about.

2. As for the result, I can understand how i2 comes from, but others
do not make sense to me.

No, you can't understand "how i2 comes from", because the erroneous "%d"
makes a complete hash of your output line.
Could you give me some pointer?

Don't feed us straight lines.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top