(int)((float)10.9 * 10)
is evaluated to 108
. Why?
IMO the (int)
-cast should be evaluated after the multiplication.
Amusingly enough, the issue here is that the expression is calculated at compile time, apparently using single precision math as expected. This happens in both debug and release builds:
// this replaces the whole operation
IL_0001: ldc.i4.s 108
IL_0003: stloc.0
IL_0004: ldloc.0
IL_0005: call void [mscorlib]System.Console::WriteLine(int32)
While the case var f =((float)10.9 * 10);int i = (int)f;
is still optimized for the multiplication, but using double precision. Because the cast is done in a separate step I guess it confuses the compiler (??):
IL_000b: ldc.r4 109 // 109 result for the first part
IL_0010: stloc.1
IL_0011: ldloc.1
IL_0012: conv.i4 // separate conversion to int
IL_0013: stloc.2
// rest is printing it
IL_0014: ldloc.1
IL_0015: box [mscorlib]System.Single
IL_001a: ldstr " "
IL_001f: ldloc.2
IL_0020: box [mscorlib]System.Int32
IL_0025: call string [mscorlib]System.String::Concat(object, object, object)
IL_002a: call void [mscorlib]System.Console::WriteLine(string)
Honestly I'd say the compiler is generating wrong code in the second case, which is probably why C++ avoids optimizing floating point code like the plague. Luckily, this is only an issue for this kind of test code which can be done fully at compile time, actual variable multiplication would be fine.
I actually tried this too:
Console.WriteLine((int)(float.Parse(Console.ReadLine()) * int.Parse(Console.ReadLine())));
and gave it 10.9 and 10, and the result was 108 as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With