2008-07-31 21 views
543

Tôi muốn sử dụng thanh theo dõi để thay đổi độ mờ của biểu mẫu.Khi áp dụng độ mờ cho một biểu mẫu, chúng tôi có nên sử dụng giá trị thập phân hoặc giá trị kép không?

Đây là mã của tôi:

decimal trans = trackBar1.Value/5000; 
this.Opacity = trans; 

Khi tôi xây dựng ứng dụng, nó mang lại cho các lỗi sau:

Cannot implicitly convert type 'decimal' to 'double' .

tôi đã cố gắng sử dụng transdouble nhưng sau đó điều khiển không hoạt động. Mã này hoạt động tốt trong một dự án VB.NET vừa qua.

+8

Ngoài ra, một số thập phân không thể đại diện rộng một giá trị như một đôi. Số thập phân chỉ có thể lên tới +/- 7.9228162514264337593543950335E + 28; trong khi Double có thể lên tới +/- 1.79769313486232E + 308 – TraumaPony

Trả lời

391

Một diễn viên rõ ràng để tăng gấp đôi như thế này là không cần thiết:

double trans = (double) trackBar1.Value/5000.0; 

Xác định hằng số như 5000.0 (hoặc như 5000d) là đủ:

double trans = trackBar1.Value/5000.0; 
double trans = trackBar1.Value/5000d; 
53

Nghe có vẻ như this.Opacity là một đôi giá trị, và trình biên dịch không thích bạn cố gắng nhồi nhét một giá trị thập phân vào nó.

112

Một câu trả lời chung chung hơn cho câu hỏi chung chung "Decimal vs đúp?": Decimal để tính toán tiền tệ để duy trì độ chính xác, đúp cho các tính toán khoa học mà không bị ảnh hưởng bởi sự khác biệt nhỏ. Vì Double là kiểu có nguồn gốc từ CPU (biểu diễn bên trong được lưu trữ trong base 2), các phép tính được thực hiện với Double hoạt động tốt hơn sau đó Decimal (được biểu diễn trong base 10 nội bộ).

55

Theo ý kiến ​​của tôi, điều mong muốn càng rõ ràng càng tốt. Điều này làm tăng thêm sự rõ ràng cho mã và hỗ trợ các lập trình viên đồng nghiệp của bạn, những người cuối cùng có thể đọc nó.

Ngoài (hoặc thay vì) chắp thêm .0 vào số, bạn có thể sử dụng decimal.ToDouble().

Dưới đây là một số ví dụ:

// Example 1 
double transperancy = trackBar1.Value/5000; 
this.Opacity = decimal.ToDouble(transperancy); 

// Example 2 - with inline temp 
this.Opacity = decimal.ToDouble(trackBar1.Value/5000); 
74

Mã của bạn làm việc tốt trong VB.NET vì nó ngầm hiện bất kỳ phôi, trong khi C# có cả những tiềm ẩn và rõ ràng.

Trong C#, chuyển đổi từ thập phân sang số hai là rõ ràng khi bạn mất độ chính xác. Ví dụ 1.1 không thể được biểu thị chính xác dưới dạng số hai, nhưng có thể là số thập phân (xem "Floating point numbers - more inaccurate than you think" vì lý do tại sao).

Trong VB chuyển đổi đã được thêm vào cho bạn bởi trình biên dịch:

decimal trans = trackBar1.Value/5000m; 
this.Opacity = (double) trans; 

Đó (double) phải được quy định rõ ràng trong C#, nhưng có thể ngụ ý bởi VB của nhiều trình biên dịch 'tha thứ'.

73

Tại sao bạn chia cho 5000? Chỉ cần đặt giá trị tối thiểu và tối đa của TrackBar từ 0 đến 100 và sau đó chia giá trị cho 100 cho tỷ lệ phần trăm Opacity.Tối thiểu 20 ví dụ dưới đây ngăn chặn các hình thức trở thành hoàn toàn vô hình:

private void Form1_Load(object sender, System.EventArgs e) 
{ 
    TrackBar1.Minimum = 20; 
    TrackBar1.Maximum = 100; 

    TrackBar1.LargeChange = 10; 
    TrackBar1.SmallChange = 1; 
    TrackBar1.TickFrequency = 5; 
} 

private void TrackBar1_Scroll(object sender, System.EventArgs e) 
{ 
    this.Opacity = TrackBar1.Value/100; 
} 
+3

Điều này không chỉ di chuyển vấn đề xung quanh? Thay vì một vấn đề với '5000', OP sẽ có vấn đề với '100'? – jww

45

Bạn nên sử dụng 5000.0 thay vì 5000.

56

Bạn có hai vấn đề. Đầu tiên, Opacity yêu cầu giá trị kép, không phải là số thập phân. Trình biên dịch cho bạn biết rằng trong khi có một chuyển đổi giữa thập phân và gấp đôi, nó là một chuyển đổi rõ ràng mà bạn cần phải xác định để nó hoạt động. Thứ hai là TrackBar.Value là một giá trị số nguyên và chia một int bởi một kết quả int trong một int không có vấn đề gì loại biến bạn gán nó vào. Trong trường hợp này có một diễn viên tiềm ẩn từ int đến thập phân hoặc kép - bởi vì không có mất độ chính xác khi bạn thực hiện phép toán - do đó trình biên dịch không phàn nàn, nhưng giá trị bạn nhận được luôn là 0, có lẽ, vì trackBar.Value là luôn nhỏ hơn 5000. Giải pháp là thay đổi mã của bạn để sử dụng gấp đôi (kiểu gốc cho Opacity) và làm số học dấu chấm động bằng cách làm cho hằng số tăng gấp đôi - điều này sẽ có tác dụng thúc đẩy số học - hoặc đúc trackBar.Value để tăng gấp đôi , sẽ làm điều tương tự - hoặc cả hai. Oh, và bạn không cần biến trung gian trừ khi nó được sử dụng ở nơi khác. Tôi đoán là trình biên dịch sẽ tối ưu hóa nó đi, anyway.

trackBar.Opacity = (double)trackBar.Value/5000.0; 
44

Thuộc tính Opacity là loại kép:

double trans = trackBar1.Value/5000.0; 
this.Opacity = trans; 

hoặc đơn giản là:

this.Opacity = trackBar1.Value/5000.0; 

hay:

this.Opacity = trackBar1.Value/5000d; 

Chú ý rằng tôi đang sử dụng 5000.0 (hoặc 5000d) để buộc một bộ phận đôi vì trackBar1.Value là một số nguyên và nó sẽ thực hiện một phân chia số nguyên và kết quả sẽ là một số nguyên.

42

Giả sử bạn đang sử dụng WinForms, Form.Opacity là loại double, vì vậy bạn nên sử dụng:

double trans = trackBar1.Value/5000.0; 
this.Opacity = trans; 

Trừ khi bạn cần giá trị ở nơi khác, nó đơn giản để viết:

this.Opacity = trackBar1.Value/5000.0; 

Lý do kiểm soát không hoạt động khi bạn thay đổi mã của mình thành đơn giản là do bạn đã có:

double trans = trackbar1.Value/5000; 

giải thích 5000 là số nguyên, vì vậy giá trị trans của bạn luôn bằng 0. Bằng cách rõ ràng làm cho số một giá trị điểm nổi bằng cách thêm .0 trình biên dịch bây giờ có thể giải thích nó như là một đôi và thực hiện tính toán thích hợp.

38

Giải pháp tốt nhất là:

this.Opacity = decimal.ToDouble(trackBar1.Value/5000); 
37

Kể từ Opacity là một giá trị gấp đôi, tôi sẽ chỉ sử dụng một đôi ngay từ đầu và không đúc ở tất cả, nhưng hãy chắc chắn sử dụng một đôi khi chia, do đó bạn don 't mất bất kỳ chính xác

Opacity = trackBar1.Value/5000.0; 
31
this.Opacity = trackBar1.Value/5000d; 
Các vấn đề liên quan