Tôi có mã đơn giản sau:
int speed1 = (int)(6.2f * 10);
float tmp = 6.2f * 10;
int speed2 = (int)tmp;
speed1
và speed2
nên có cùng giá trị, nhưng thực tế, tôi có:
speed1 = 61
speed2 = 62
Tôi biết có lẽ tôi nên sử dụng Math.Round thay vì truyền, nhưng tôi muốn hiểu tại sao các giá trị lại khác nhau.
Tôi đã xem mã byte được tạo, nhưng ngoại trừ một cửa hàng và tải, các opcode đều giống nhau.
Tôi cũng đã thử mã tương tự trong java và tôi đã nhận được chính xác 62 và 62.
Ai đó có thể giải thích điều này?
Chỉnh sửa: Trong mã thực, nó không trực tiếp 6.2f * 10 mà là một hàm gọi * một hằng số. Tôi có mã byte sau:
cho speed1
:
IL_01b3: ldloc.s V_8
IL_01b5: callvirt instance float32 myPackage.MyClass::getSpeed()
IL_01ba: ldc.r4 10.
IL_01bf: mul
IL_01c0: conv.i4
IL_01c1: stloc.s V_9
cho speed2
:
IL_01c3: ldloc.s V_8
IL_01c5: callvirt instance float32 myPackage.MyClass::getSpeed()
IL_01ca: ldc.r4 10.
IL_01cf: mul
IL_01d0: stloc.s V_10
IL_01d2: ldloc.s V_10
IL_01d4: conv.i4
IL_01d5: stloc.s V_11
chúng ta có thể thấy rằng toán hạng là số float và sự khác biệt duy nhất là stloc/ldloc
.
Đối với máy ảo, tôi đã thử với Mono / Win7, Mono / MacOS và .NET / Windows, với kết quả tương tự.