К сожалению, вы выбрали плохой пример.JIT-компилятор x86 не содержит встроенных методов, возвращающих float.Не уверен на 100%, почему, я думаю, это помогает избежать постоянных проблем, когда число с плавающей запятой преобразуется в 80-битное значение с плавающей запятой в FPU.Внутренняя точность составляет 80 бит, но эти дополнительные биты обрезаются, когда 80-битное значение усекается до 32-битного значения, когда оно сбрасывается обратно в память.Слишком длительное сохранение значения в FPU предотвращает возникновение этого усечения и приводит к изменению результата вычисления.
Если вы замените float на double и скомпилируете этот код:
static void Main(string[] args) {
Console.WriteLine(Cube(2.0));
}
Тогда этот машинный кодгенерируется при включенном оптимизаторе JIT:
00000000 push ebp ; setup stack frame
00000001 mov ebp,esp
00000003 call 6DA2BEF0 ; Console.get_Out()
00000008 fld qword ptr ds:[010914B0h] ; ST0 = 8.0
0000000e sub esp,8 ; setup argument for WriteLine
00000011 fstp qword ptr [esp]
00000014 mov ecx,eax ; call Console.Out.WriteLine
00000016 mov eax,dword ptr [ecx]
00000018 call dword ptr [eax+000000D0h]
0000001e pop ebp ; done
0000001f ret
Он не только встроил функции, но и мог вычислять выражения во время компиляции.И напрямую передает результат, вызывая Console.WriteLine (8.0).Довольно хорошо, да?
Используй double, а не float.