Tôi đã nhận thấy một hành vi thú vị với việc làm tròn/cắt phao bằng trình biên dịch C#. Cụ thể, khi một float float nằm ngoài phạm vi biểu diễn được bảo đảm (7 chữ số thập phân), thì a) đúc một kết quả float cho float (một hoạt động không cần thiết ngữ nghĩa) và b) lưu trữ kết quả tính toán trung gian trong biến cục bộ thay đổi đầu ra. Một ví dụ:Hành vi biên dịch lạ với các ký tự float và các biến float
using System;
class Program
{
static void Main()
{
float f = 2.0499999f;
var a = f * 100f;
var b = (int) (f * 100f);
var c = (int) (float) (f * 100f);
var d = (int) a;
var e = (int) (float) a;
Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
Console.WriteLine(d);
Console.WriteLine(e);
}
}
Đầu ra là:
205
204
205
205
205
Trong JITted debug xây dựng trên máy tính của tôi, b được tính như sau:
var b = (int) (f * 100f);
0000005a fld dword ptr [ebp-3Ch]
0000005d fmul dword ptr ds:[035E1648h]
00000063 fstp qword ptr [ebp-5Ch]
00000066 movsd xmm0,mmword ptr [ebp-5Ch]
0000006b cvttsd2si eax,xmm0
0000006f mov dword ptr [ebp-44h],eax
trong khi d được tính như
var d = (int) a;
00000096 fld dword ptr [ebp-40h]
00000099 fstp qword ptr [ebp-5Ch]
0000009c movsd xmm0,mmword ptr [ebp-5Ch]
000000a1 cvttsd2si eax,xmm0
000000a5 mov dword ptr [ebp-4Ch],eax
Cuối cùng, nhiệm vụ của tôi trên: tại sao dòng thứ hai của đầu ra khác với thứ tư? Liệu fmul đó có tạo ra sự khác biệt như vậy không? Cũng lưu ý rằng nếu chữ số cuối cùng (không thể đại diện) từ phao f bị loại bỏ hoặc thậm chí bị giảm, mọi thứ "rơi vào vị trí".
tôi thấy câu trả lời cho câu hỏi này ở đây nhưng không thể tìm thấy nó – Andrey