I am having trouble with:
int q = 150;
float s = 0.7f;
float z = q*s;
int z1 = (int) (q*s);
int z2 = (int) z;
This results in
z1
beingint
with value104
z2
beingint
with value105
Can anyone explain this? I do not understand these results.
To avoid closing, I (René Vogt) add this information:
q*s
results in afloat
of value105.0f
(or maybe104.999999
, but a string represention ends up as105
).- so
z
is afloat
of105
The question now is, why (int)z
results in 105
, but (int)(q*s)
results in 104
? I can reproduce this on my machine (i7, Win10, VS2015, .NET4.6.1)
And the IL code:
// Initialisation
// q = 150
ldc.i4 0x96
stloc.0
// s = 0.7f
ldc.r4 0.69999999
stloc.1
// calculating z
ldloc.0 // load q
conv.r4 // convert to float
ldloc.1 // load s
mul // q*s
stloc.2 // store float result to z
// calulating z1
ldloc.0 // load q
conv.r4 // convert to float
ldloc.1 // load s
mul // q*s
conv.i4 // convert to int
stloc.3 // store int result in z1 => 104!
// calculating z2
ldloc.2 // loading float z
conv.i4 // converting to int
stloc.s // write to z2 (last local variable -> "s" as stack address)
// => 105
So I think the only difference between z1
and z2
is that for z2
the intermediate float
result gets written from the register to the local variable's (z
) storage place. But how would that affect the result?