Thí dụ:
float timeRemaining = 0.58f;
Tại sao lại f
bắt buộc phải có ở cuối con số này?
Thí dụ:
float timeRemaining = 0.58f;
Tại sao lại f
bắt buộc phải có ở cuối con số này?
double & int
.
Câu trả lời:
Khai báo float của bạn có hai phần:
timeRemaining
là kiểu float
.0.58
cho biến này.Vấn đề xảy ra ở phần 2.
Phía bên tay phải được tự đánh giá. Theo đặc tả C #, một số chứa dấu thập phân không có hậu tố được hiểu là a double
.
Vì vậy, bây giờ chúng ta có một double
giá trị mà chúng ta muốn gán cho một biến kiểu float
. Để làm được điều này, phải có một chuyển đổi ngầm định từ double
thành float
. Không có chuyển đổi như vậy, bởi vì bạn có thể (và trong trường hợp này là) mất thông tin trong chuyển đổi.
Lý do là giá trị được trình biên dịch sử dụng không thực sự là 0,58 mà là giá trị dấu phẩy động gần nhất với 0,58, là 0,57999999999999978655962351581366 ... cho double
và chính xác là 0,579999946057796478271484375 cho float
.
Nói một cách chính xác, f
là không bắt buộc. Bạn có thể tránh phải sử dụng f
hậu tố bằng cách chuyển giá trị thành float
:
float timeRemaining = (float)0.58;
(float) 0.58
? Trước đó bạn đã nói rằng không có chuyển đổi, vì thông tin có thể bị mất, sau đó làm thế nào đến diễn viên sẽ hoạt động?
2.4
được hiểu là một kép ở mọi nơi khác. 2. Không cho phép các chuyển đổi thu hẹp ngầm định (như từ double sang float). Nếu bạn muốn tạo một ngoại lệ cho những quy tắc này, thì bạn phải có một lý do chính đáng. Lưu 1 hành trình phím có thể không đủ tốt.
Bởi vì có một số kiểu số mà trình biên dịch có thể sử dụng để biểu diễn giá trị 0.58
:float
, double
và decimal
. Trừ khi bạn đồng ý với việc chọn một trình biên dịch cho bạn, bạn phải xác định rõ.
Tài liệu cho double
biết rằng nếu bạn không tự mình chỉ định loại, trình biên dịch luôn chọn double
là loại của bất kỳ ký tự số thực nào:
Theo mặc định, một ký tự số thực ở phía bên phải của toán tử gán được coi là kép. Tuy nhiên, nếu bạn muốn một số nguyên được coi là gấp đôi, hãy sử dụng hậu tố d hoặc D.
Thêm hậu tố f
tạo ra một float
; hậu tố d
tạo ra mộtdouble
; hậu tố m
tạo ra a decimal
. Tất cả những thứ này cũng hoạt động ở dạng chữ hoa.
Tuy nhiên, điều này vẫn chưa đủ để giải thích tại sao điều này không biên dịch:
float timeRemaining = 0.58;
Nửa còn thiếu của câu trả lời là việc chuyển đổi từ double
0.58
đến float
timeRemaining
khả năng mất thông tin, do đó trình biên dịch từ chối áp dụng nó ngầm. Nếu bạn thêm một diễn viên rõ ràng thì chuyển đổi sẽ được thực hiện; nếu bạn thêm f
hậu tố thì không cần chuyển đổi. Trong cả hai trường hợp, mã sau đó sẽ được biên dịch.
int
và một cho double
.
double a = 0.69f;
nào?
float
sang double
.
Vấn đề là .NET, để cho phép một số loại hoạt động ngầm được thực hiện liên quan đến float
vàdouble
, cần phải chỉ định rõ ràng điều gì sẽ xảy ra trong tất cả các tình huống liên quan đến toán hạng hỗn hợp hoặc cho phép chuyển đổi ngầm giữa các loại được thực hiện trong một chỉ hướng; Microsoft đã chọn đi theo hướng dẫn đầu của Java trong việc cho phép hướng mà đôi khi ủng hộ độ chính xác, nhưng thường hy sinh tính đúng đắn và thường gây ra rắc rối.
Trong hầu hết các trường hợp, lấy double
giá trị gần nhất với một đại lượng số cụ thể và gán nó cho a float
sẽ mang lại float
giá trị gần nhất với cùng đại lượng đó. Có một vài trường hợp góc, chẳng hạn như giá trị 9,007,199,791,611,905; float
đại diện tốt nhất sẽ là 9,007,200,328,482,816 (giảm bởi 536,870,911), nhưng đúc double
đại diện tốt nhất (tức là 9,007,199,791,611,904) để float
tạo ra 9,007,199,254,740,992 (giảm 536,870,913). Mặc dù vậy, nói chung, việc chuyển đổi double
biểu diễn tốt nhất của một số đại lượng thành float
sẽ mang lại biểu diễn tốt nhất có thể float
, hoặc một trong hai biểu diễn về cơ bản tốt như nhau.
Lưu ý rằng hành vi mong muốn này áp dụng ngay cả ở các cực điểm; ví dụ: float
biểu diễn tốt nhất cho đại lượng 10 ^ 308 khớp với float
biểu diễn đạt được bằng cách chuyển đổi double
biểu diễn tốt nhất của đại lượng đó. Tương tự như vậy, float
biểu diễn tốt nhất của 10 ^ 309 khớp với float
biểu diễn đạt được bằng cách chuyển đổi double
biểu diễn tốt nhất của đại lượng đó.
Thật không may, các chuyển đổi theo hướng không yêu cầu diễn viên rõ ràng hiếm khi ở bất kỳ đâu gần chính xác. Việc chuyển đổi float
biểu diễn tốt nhất của một giá trị thành double
sẽ hiếm khi mang lại bất kỳ điều gì đặc biệt gần với double
biểu diễn tốt nhất của giá trị đó và trong một số trường hợp, kết quả có thể bị sai lệch hàng trăm bậc (ví dụ: chuyển đổi float
biểu diễn tốt nhất của 10 ^ 40 thành double
sẽ mang lại một giá trị so sánh lớn hơn double
đại diện tốt nhất của 10 ^ 300.
Than ôi, các quy tắc chuyển đổi là những gì họ đang có, vì vậy người ta phải sống với việc sử dụng các định dạng và hậu tố ngớ ngẩn khi chuyển đổi các giá trị theo hướng "an toàn" và hãy cẩn thận với các định dạng ngầm theo hướng nguy hiểm thường sẽ mang lại kết quả không có thật.
double
.