2010-07-10 21 views
6

1) Nếu một toán hạng có loại ulong, trong khi toán hạng còn lại thuộc loại sbyte/short/int/long thì lỗi biên dịch xảy ra. Tôi không thấy logic trong việc này. Do đó, tại sao lại là ý tưởng tồi cho cả hai toán hạng được thăng cấp thành loại double hoặc float?Thay vì lỗi, tại sao cả hai toán hạng đều không được thăng hạng hoặc tăng gấp đôi?

 long L = 100; 
     ulong UL = 1000; 
     double d = L + UL; // error saying + operator can't be applied 
           to operands of type ulong and long 

b) Trình biên dịch ngầm chuyển đổi int đen vào byte loại và gán giá trị dẫn đến b:

byte b = 1; 

Nhưng nếu chúng ta cố gắng gán một chữ kiểu ulonglong (hoặc với các loại int , byte v.v.), trình biên dịch báo cáo lỗi:

long L = 1000UL; 

Tôi nghĩ rằng trình biên dịch sẽ có thể tìm ra liệu kết quả của biểu thức liên tục có thể phù hợp với biến loại long?!

cảm ơn bạn

Trả lời

8

Để trả lời câu hỏi được đánh dấu (1) - thêm thời gian đã ký và chưa ký có thể là lỗi . Nếu ý định của nhà phát triển là tràn vào không chính xác số học trong trường hợp này thì đó là điều họ nên làm một cách rõ ràng, bằng cách đúc cả hai đối số để tăng gấp đôi. Làm như vậy hoàn toàn là các lỗi ẩn thường xuyên hơn là làm điều đúng.

Để trả lời câu hỏi được đánh dấu (b) - tất nhiên trình biên dịch có thể tìm ra điều đó. Rõ ràng nó có thể bởi vì nó làm như vậy cho các chữ số nguyên. Nhưng một lần nữa, điều này gần như chắc chắn là một lỗi. Nếu bạn có ý định đặt một ký hiệu dài thì tại sao bạn đánh dấu nó là chưa ký? Điều này có vẻ như một lỗi . C# đã được thiết kế cẩn thận sao cho nó trông có vẻ lạ lẫm như thế này và gọi sự chú ý của bạn đến họ, thay vì đoán xem bạn có ý định nói điều kỳ lạ này và thèm muốn như thể mọi thứ đều bình thường. Trình biên dịch đang cố khuyến khích bạn viết mã hợp lý; mã hợp lý không trộn các loại đã ký và chưa ký.

+0

"Để trả lời câu hỏi được đánh dấu (1) - thêm thời gian đã ký và chưa ký có thể là một sai lầm". Trong ví dụ của tôi mà có thể là trường hợp. Nhưng với ví dụ phức tạp hơn, UL có thể có nhiều biểu thức trong đó giá trị kết quả cũng phải dương và do đó UL là loại ulong sẽ có ý nghĩa. Nhưng sẽ rất lạ khi các lập trình viên cũng sử dụng biến UL sau này trong mã (do đó sau những biểu thức mà giá trị kết quả là dương) trong các biểu thức như double "d = L + UL" Uh, thậm chí tôi không chắc chắn nếu lý luận của tôi có ý nghĩa gì – flockofcode

2

Tại sao nên?

Nói chung, 2 loại không tương thích vì đã ký dài. Bạn chỉ đang mô tả một trường hợp đặc biệt.

Đối byte b = 1; 1 không có loại tiềm ẩn như vậy và có thể bị cưỡng chế vào byte

Đối long L = 1000UL; "1000UL" không có một loại rõ ràng và không tương thích và xem trường hợp chung của tôi ở trên.

Ví dụ từ "ulong" on MSDN:

When an integer literal has no suffix, its type is the first of these types in which its value can be represented: int, uint, long, ulong.

và sau đó

There is no implicit conversion from ulong to any integral type

On "dài" trong MSDN (đậm của tôi)

When an integer literal has no suffix, its type is the first of these types in which its value can be represented: int, uint, long, ulong.

Đó là khá phổ biến và hợp lý và hoàn toàn dự đoán

1

câu trả lời đơn giản là đó chỉ là cách spec ngôn ngữ được viết:

http://msdn.microsoft.com/en-us/library/y5b434w4(v=VS.80).aspx

Bạn có thể tranh luận về việc liệu các quy tắc chuyển đổi tiềm ẩn là logic trong từng trường hợp, nhưng vào cuối ngày đây là những chỉ các quy tắc mà ủy ban thiết kế quyết định.

Bất kỳ chuyển đổi ngầm nào đều có nhược điểm ở chỗ nó làm điều gì đó mà người lập trình có thể không mong đợi. Hiệu trưởng chung với C# dường như là lỗi trong những trường hợp này thay vì sau đó cố gắng đoán ý nghĩa của lập trình viên.

2
long l = 100; 
ulong ul = 1000; 
double d = l + ul; // error 

Why would it be bad idea for both operands to instead be promoted to type double or float?

Mà một trong những? Nổi? Hay tăng gấp đôi? Hoặc có thể là số thập phân? Hay lâu dài?Không có cách nào để trình biên dịch biết bạn đang nghĩ gì. Cũng nhập thông tin thường chảy ra khỏi các biểu thức không vào chúng, vì vậy nó không thể sử dụng mục tiêu của nhiệm vụ để chọn một trong hai.

Khắc phục là chỉ cần chỉ định loại bạn muốn bằng cách truyền một hoặc cả hai đối số cho loại đó.

+0

"Cái nào? Floats? Hay gấp đôi? Hoặc có thể là số thập phân? Hay dài? Không có cách nào để trình biên dịch biết bạn đang nghĩ gì." Cùng một đối số có thể được sử dụng với "double d = b + i"; trong đó b là loại byte và i của kiểu int. – flockofcode

+1

@flockofcode: Đó không phải là tình huống tương tự. Với ví dụ mới của bạn có một diễn viên tiềm ẩn từ byte đến một số nguyên để bổ sung là hai số nguyên. Và có một quy tắc khác cho biết kết quả của biểu thức (một số nguyên) có thể được chuyển đổi hoàn toàn thành một double. Không có sự mơ hồ ở đây. –

2

Trình biên dịch không xem xét những gì bạn làm với kết quả khi nó xác định loại kết quả của biểu thức. Các quy tắc về cách các loại được quảng bá trong một biểu thức chỉ xem xét các giá trị trong chính biểu thức, chứ không phải những gì bạn làm với giá trị sau này.

Trong trường hợp bạn gán kết quả cho một biến, nó có thể là có thể sử dụng thông tin đó, nhưng hãy cân nhắc một tuyên bố như thế này:

Console.Write(L + UL); 

Phương pháp Write có quá tải mà mất các kiểu dữ liệu khác nhau , điều này sẽ làm cho nó khá phức tạp để quyết định cách sử dụng thông tin đó. Ví dụ, có quá tải phải mất một chuỗi, vì vậy một cách có thể để quảng bá các loại (và một ứng cử viên tốt vì nó không mất bất kỳ độ chính xác nào) sẽ chuyển đổi cả hai giá trị thành chuỗi và sau đó ghép nối chúng, có lẽ không phải là kết quả mà bạn đã theo đuổi.

0

Giả sử một biến bằng 9223372036854775807 và biến còn lại bằng -9223372036854775806? Kết quả của việc bổ sung là gì? Việc chuyển đổi hai giá trị thành double sẽ làm tròn chúng thành 9223372036854775808 và -9223372036854775808, tương ứng; thực hiện phép trừ sau đó sẽ mang lại 0,0 (chính xác). Ngược lại, nếu cả hai giá trị được ký, kết quả sẽ là 1.0 (cũng chính xác). Nó có thể chuyển đổi cả hai toán hạng thành loại Decimal và thực hiện toán học chính xác. Tuy nhiên, chuyển đổi sang Double sau khi thực tế sẽ yêu cầu một diễn viên rõ ràng.

Các vấn đề liên quan