แปลงทศนิยมให้เป็นสองเท่า


673

ฉันต้องการใช้ a Track-Barเพื่อเปลี่ยนFormความทึบของ

นี่คือรหัสของฉัน:

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

เมื่อฉันสร้างแอปพลิเคชันมันทำให้เกิดข้อผิดพลาดต่อไปนี้:

ไม่สามารถแปลงประเภทdecimalเป็นdouble

ผมได้ลองใช้transและdoubleแต่แล้วControlไม่ทำงาน รหัสนี้ทำงานได้ดีในโครงการ VB.NET ที่ผ่านมา


11
นอกจากนี้ทศนิยมไม่สามารถแทนค่าความกว้างเป็นสองเท่า ทศนิยมสามารถเพิ่มได้ถึง +/- 7.9228162514264337593543950335E + 28; ในขณะที่ Double สามารถขึ้นไปที่ +/- 1.79769313486232E + 308
TraumaPony


8
บางคนควรทำเครื่องหมายสิ่งนี้ว่าซ้ำซ้อน
อีวาน

8
@Ivan: นี่เป็นคำถามที่ 4 ที่ถามกันมาตลอดเลย ...
Nikolas

1
@ Nikolas: แน่นอน ติดตามที่นี่วันนี้
มิ.ย.

คำตอบ:


447

doubleไม่จำเป็นต้องใช้แคสต์แบบชัดเจนเช่นนี้:

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

การระบุค่าคงที่เป็น5000.0(หรือเป็น5000d) ก็เพียงพอแล้ว:

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

123

คำตอบทั่วไปสำหรับคำถามทั่วไป "Decimal vs Double?": ทศนิยมสำหรับการคำนวณทางการเงินเพื่อรักษาความแม่นยำDoubleสำหรับการคำนวณทางวิทยาศาสตร์ที่ไม่ได้รับผลกระทบจากความแตกต่างเล็กน้อย เนื่องจาก Double เป็นประเภทที่มีกำเนิดมาจาก CPU (การเป็นตัวแทนภายในถูกเก็บไว้ในฐาน 2 ) การคำนวณที่ทำด้วย Double จะทำงานได้ดีกว่า Decimal (ซึ่งแสดงในฐาน 10ภายใน)


83

รหัสของคุณทำงานได้ดีใน VB.NET เพราะมันจะปลดเปลื้องใด ๆ ในขณะที่ C # มีทั้งโดยนัยและชัดเจน

ใน C # การแปลงจากทศนิยมเป็นสองเท่าจะชัดเจนเมื่อคุณเสียความแม่นยำ ยกตัวอย่างเช่น 1.1 ไม่สามารถแสดงอย่างถูกต้องเป็นสองเท่า แต่สามารถเป็นทศนิยมได้ (ดู " หมายเลขจุดลอยตัว - ไม่ถูกต้องมากกว่าที่คุณคิด " เพราะเหตุผล)

ใน VB การคอมไพเลอร์ถูกเพิ่มสำหรับคุณโดย:

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

ที่(double)จะต้องมีการระบุไว้อย่างชัดเจนใน C # แต่สามารถแปลโดยคอมไพเลอร์ 'ให้อภัย' ของ VB


80

ทำไมคุณหารด้วย 5,000 เพียงแค่ตั้งค่าต่ำสุดและสูงสุดของ TrackBar ระหว่าง 0 และ 100 จากนั้นหารค่า 100 ด้วยเปอร์เซ็นต์ความทึบ ตัวอย่างขั้นต่ำ 20 ตัวอย่างด้านล่างป้องกันไม่ให้มองไม่เห็นฟอร์ม:

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;
}

5
นี่จะไม่ย้ายปัญหาไปใช่ไหม แทนที่จะมีปัญหากับ5000OP จะมีปัญหากับ100?
jww

62

คุณมีสองปัญหา ก่อนอื่นOpacityต้องใช้ค่าสองเท่าไม่ใช่ค่าทศนิยม คอมไพเลอร์กำลังบอกคุณว่าในขณะที่มีการแปลงระหว่างทศนิยมและสองเท่ามันเป็นการแปลงที่ชัดเจนที่คุณต้องระบุเพื่อให้มันทำงาน อย่างที่สองก็TrackBar.Valueคือค่าจำนวนเต็มและการหาร int ด้วยผลลัพธ์ int ในการ int ไม่ว่าชนิดของตัวแปรที่คุณกำหนดให้ ในกรณีนี้มีการส่งโดยนัยจาก int ถึงทศนิยมหรือสองเท่า - เนื่องจากไม่มีการสูญเสียความแม่นยำเมื่อคุณทำการส่ง - ดังนั้นคอมไพเลอร์ไม่บ่น แต่ค่าที่คุณได้รับคือ 0 เสมอเนื่องจากtrackBar.Valueอยู่เสมอน้อยกว่า 5000 การแก้ปัญหาคือการเปลี่ยนรหัสของคุณเพื่อใช้คู่ (ประเภทพื้นเมืองสำหรับความทึบ) และไม่ลอยคำนวณจุดโดยชัดเจนการทำอย่างต่อเนื่องสอง - ซึ่งจะมีผลในการส่งเสริมคณิตศาสตร์ - หรือหล่อtrackBar.Valueสองครั้ง ซึ่งจะทำสิ่งเดียวกัน - หรือทั้งสองอย่าง โอ้และคุณไม่ต้องการตัวแปรกลางเว้นแต่ว่าจะใช้ที่อื่น ฉันเดาว่าคอมไพเลอร์จะปรับมันให้เหมาะสม

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

58

ในความคิดของฉันมันเป็นที่พึงปรารถนาที่จะเป็นที่ชัดเจนที่สุด สิ่งนี้จะช่วยเพิ่มความชัดเจนให้กับโค้ดและช่วยโปรแกรมเมอร์ของคุณที่อาจอ่านมันในที่สุด

นอกเหนือไป (หรือแทน) ผนวกไปยังหมายเลขที่คุณสามารถใช้ .0decimal.ToDouble()

นี่คือตัวอย่างบางส่วน:

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

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

57

ดูเหมือนว่าthis.Opacityจะเป็นค่าสองเท่าและคอมไพเลอร์ไม่ชอบคุณพยายามยัดค่าทศนิยมลงไป


50

ทึบคุณสมบัติเป็นประเภทคู่:

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

หรือเพียงแค่:

this.Opacity = trackBar1.Value / 5000.0;

หรือ:

this.Opacity = trackBar1.Value / 5000d;

สังเกตว่าฉันกำลังใช้5000.0(หรือ5000d) เพื่อบังคับให้มีการหารสองครั้งเพราะtrackBar1.Valueเป็นจำนวนเต็มและมันจะทำการหารจำนวนเต็มและผลลัพธ์จะเป็นจำนวนเต็ม



47

สมมติว่าคุณใช้ WinForms Form.Opacityอยู่ในประเภทdoubleดังนั้นคุณควรใช้:

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

ยกเว้นว่าคุณต้องการค่าอื่นการเขียนง่ายกว่า:

this.Opacity = trackBar1.Value / 5000.0;

เหตุผลที่การควบคุมไม่ทำงานเมื่อคุณเปลี่ยนรหัสของคุณให้เป็นแบบ double นั้นเป็นเพราะคุณมี:

double trans = trackbar1.Value / 5000;

ซึ่งตีความ5000ว่าเป็นจำนวนเต็มและเพราะtrackbar1.Valueยังเป็นจำนวนเต็มtransค่าของคุณเป็นศูนย์เสมอ โดยการทำให้ตัวเลขเป็นค่าทศนิยมอย่างชัดเจนโดยการเพิ่ม.0คอมไพเลอร์ตอนนี้สามารถตีความมันเป็นสองเท่าและทำการคำนวณที่เหมาะสม



41

เนื่องจากOpacityเป็นค่าสองเท่าฉันจะใช้ double จาก outset และไม่ร่ายเลย แต่ให้ใช้ double เมื่อแบ่งดังนั้นคุณจะไม่สูญเสียความแม่นยำใด ๆ

Opacity = trackBar1.Value / 5000.0;


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.