อะไรคือข้อดีและข้อเสียของการใช้ตัวอื่นแทนใน C ++?
อะไรคือข้อดีและข้อเสียของการใช้ตัวอื่นแทนใน C ++?
คำตอบ:
หากคุณต้องการที่จะรู้คำตอบที่จริงคุณควรอ่าน อะไรทุกนักวิทยาศาสตร์คอมพิวเตอร์ควรรู้เกี่ยวกับจุดลอยเลขคณิต
ในระยะสั้นแม้ว่าจะdouble
ช่วยให้มีความแม่นยำสูงขึ้นในการนำเสนอ แต่สำหรับการคำนวณบางอย่างก็จะทำให้เกิดข้อผิดพลาดมากขึ้น "สิทธิ" ทางเลือกคือใช้เป็นที่มีความแม่นยำมากที่สุดเท่าที่คุณต้องการ แต่ไม่ได้มากขึ้นและเลือกขั้นตอนวิธีการที่เหมาะสม
คอมไพเลอร์จำนวนมากทำคณิตศาสตร์ทศนิยมแบบขยายในโหมด "ไม่เข้มงวด" อยู่ดี (เช่นใช้ประเภทจุดลอยตัวที่กว้างกว่าที่มีอยู่ในฮาร์ดแวร์เช่น 80 บิตและ 128 บิตลอยตัว) สิ่งนี้ควรนำมาพิจารณาด้วยเช่นกัน ในทางปฏิบัติคุณแทบจะไม่เห็นความแตกต่างของความเร็วเลย - พวกมันเป็นแบบดั้งเดิมของฮาร์ดแวร์อยู่แล้ว
double
- จะปลอดภัยกว่าในกรณีส่วนใหญ่
ถ้าคุณไม่มีเหตุผลเฉพาะบางอย่างให้ใช้ double
อาจจะน่าแปลกใจที่มันเป็นสองเท่าและไม่ใช่ลอยซึ่งเป็นประเภทจุดลอยตัว "ปกติ" ใน C (และ C ++) ฟังก์ชันทางคณิตศาสตร์มาตรฐานเช่นsinและlogใช้เป็นอาร์กิวเมนต์สองเท่าและส่งกลับค่า doubles ลิเทอรัลทศนิยมปกติเช่นเดียวกับเมื่อคุณเขียน3.14ในโปรแกรมของคุณจะมีประเภท double ไม่ลอย.
ในคอมพิวเตอร์สมัยใหม่ทั่วไปการเพิ่มเป็นสองเท่าอาจเร็วพอ ๆ กับการลอยตัวหรือเร็วกว่าดังนั้นประสิทธิภาพมักไม่ใช่ปัจจัยที่ต้องพิจารณาแม้จะเป็นการคำนวณจำนวนมากก็ตาม (และสิ่งเหล่านี้จะต้องเป็นการคำนวณจำนวนมากหรือประสิทธิภาพก็ไม่ควรเข้ามาในใจคุณคอมพิวเตอร์เดสก์ท็อป i7 เครื่องใหม่ของฉันสามารถคูณหกพันล้านคูณสองในหนึ่งวินาที)
คำถามนี้ไม่สามารถตอบได้เนื่องจากไม่มีบริบทของคำถาม สิ่งที่อาจส่งผลต่อการเลือกมีดังนี้
การใช้งานคอมไพเลอร์ของโฟลตคู่ผสมและแบบยาว สถานะมาตรฐาน C ++:
จุดลอยตัวมีสามประเภท: ลอยคู่และคู่ยาว ประเภท double ให้ความแม่นยำอย่างน้อยเท่ากับ float และ type long double จะให้ความแม่นยำอย่างน้อยเท่ากับ double
ดังนั้นทั้งสามจึงมีขนาดเท่ากันในหน่วยความจำ
การมีอยู่ของ FPU ซีพียูบางตัวไม่ได้มี FPU และบางครั้งก็มีการจำลองประเภทจุดลอยตัวและบางครั้งก็ไม่รองรับประเภทจุดลอยตัว
สถาปัตยกรรม FPU FPU ของ IA32 คือ 80 บิตภายใน - 32 บิตและ 64 บิตลอยได้ขยายเป็น 80 บิตเมื่อโหลดและลดลงในร้านค้า นอกจากนี้ยังมี SIMD ที่สามารถลอย 32 บิตสี่ตัวหรือ 64 บิตสองตัวในแบบคู่ขนาน การใช้ SIMD ไม่ได้กำหนดไว้ในมาตรฐานดังนั้นจึงต้องใช้คอมไพเลอร์ที่ทำการวิเคราะห์ที่ซับซ้อนมากขึ้นเพื่อตรวจสอบว่าสามารถใช้ SIMD ได้หรือไม่หรือต้องใช้ฟังก์ชันพิเศษ (ไลบรารีหรือภายใน) ผลลัพธ์ของรูปแบบภายใน 80 บิตคือคุณจะได้ผลลัพธ์ที่แตกต่างกันเล็กน้อยขึ้นอยู่กับความถี่ในการบันทึกข้อมูลลงใน RAM (ทำให้สูญเสียความแม่นยำ) ด้วยเหตุนี้คอมไพเลอร์จึงไม่ปรับแต่งโค้ดทศนิยมให้เหมาะสมโดยเฉพาะ
แบนด์วิดท์หน่วยความจำ หากคู่ต้องการพื้นที่เก็บข้อมูลมากกว่าโฟลตการอ่านข้อมูลจะใช้เวลานานขึ้น นั่นเป็นคำตอบที่ไร้เดียงสา ใน IA32 สมัยใหม่ทุกอย่างขึ้นอยู่กับว่าข้อมูลมาจากไหน หากอยู่ในแคช L1 การโหลดจะน้อยมากหากข้อมูลมาจากบรรทัดแคชเดียว หากครอบคลุมมากกว่าหนึ่งบรรทัดแคชจะมีค่าใช้จ่ายเล็กน้อย หากมาจาก L2 จะใช้เวลานานกว่านั้นหากอยู่ใน RAM ก็จะยังคงอยู่อีกต่อไปและสุดท้ายถ้าอยู่ในดิสก์ก็เป็นเวลาที่ดี ดังนั้นการเลือก float หรือ double จึงมีความสำคัญน้อยกว่าวิธีการใช้ข้อมูล หากคุณต้องการคำนวณขนาดเล็กสำหรับข้อมูลตามลำดับจำนวนมากควรใช้ประเภทข้อมูลขนาดเล็ก การคำนวณจำนวนมากในชุดข้อมูลขนาดเล็กจะช่วยให้คุณใช้ประเภทข้อมูลที่ใหญ่ขึ้นและมีผลอย่างมาก ถ้าคุณ' การเข้าถึงข้อมูลแบบสุ่มมากดังนั้นการเลือกขนาดข้อมูลจึงไม่สำคัญ - ข้อมูลถูกโหลดในเพจ / บรรทัดแคช ดังนั้นแม้ว่าคุณจะต้องการแค่ไบต์จาก RAM แต่คุณก็สามารถถ่ายโอนได้ 32 ไบต์ (ซึ่งขึ้นอยู่กับสถาปัตยกรรมของระบบ) เหนือสิ่งอื่นใด CPU / FPU อาจเป็น super-scalar (aka pipelined) ดังนั้นแม้ว่าการโหลดอาจใช้เวลาหลายรอบ CPU / FPU อาจยุ่งอยู่กับการทำอย่างอื่น (เช่นการคูณ) ที่ซ่อนเวลาในการโหลดไว้ที่ระดับหนึ่ง
มาตรฐานไม่ได้บังคับใช้รูปแบบเฉพาะสำหรับค่าทศนิยม
หากคุณมีข้อมูลจำเพาะสิ่งนั้นจะแนะนำคุณไปสู่ทางเลือกที่ดีที่สุด มิฉะนั้นก็ลงประสบการณ์ว่าจะใช้อะไร
Double มีความแม่นยำมากขึ้น แต่ถูกเข้ารหัสเป็น 8 ไบต์ float มีขนาดเพียง 4 ไบต์ดังนั้นจึงมีพื้นที่น้อยลงและมีความแม่นยำน้อยลง
คุณควรระวังให้มากหากคุณมี double and float ในแอปพลิเคชันของคุณ ฉันมีข้อบกพร่องเนื่องจากในอดีต ส่วนหนึ่งของรหัสใช้ float ในขณะที่ส่วนที่เหลือของรหัสใช้ double การคัดลอกสองครั้งเพื่อลอยแล้วลอยเป็นสองเท่าอาจทำให้เกิดข้อผิดพลาดที่แม่นยำซึ่งอาจส่งผลกระทบอย่างมาก ในกรณีของฉันมันเป็นโรงงานเคมี ... หวังว่ามันจะไม่ส่งผลกระทบอย่างมาก :)
คิดว่าเป็นเพราะบั๊กแบบนี้ที่จรวด Ariane 6 ระเบิดเมื่อไม่กี่ปีก่อน !!!
คิดอย่างรอบคอบเกี่ยวกับประเภทที่จะใช้สำหรับตัวแปร
ตัวฉันมักจะเพิ่มขึ้นเป็นสองเท่าตลอดเวลาจนกระทั่งฉันเห็นปัญหาคอขวด จากนั้นฉันจะพิจารณาย้ายไปลอยหรือเพิ่มประสิทธิภาพส่วนอื่น ๆ
ขึ้นอยู่กับวิธีการที่คอมไพเลอร์ดำเนินการสองครั้ง ถูกกฎหมายสำหรับ double และ float เป็นประเภทเดียวกัน (และอยู่ในบางระบบ)
ที่กล่าวมาหากแตกต่างกันจริงๆประเด็นหลักคือความแม่นยำ คู่มีความแม่นยำสูงกว่ามากเนื่องจากขนาดต่างกัน หากตัวเลขที่คุณใช้มักจะเกินค่าของลูกลอยให้ใช้เลขคู่
คนอื่น ๆ หลายคนได้กล่าวถึงเรื่องประสิทธิภาพ นั่นจะเป็นสิ่งสุดท้ายในรายการการพิจารณาของฉัน ความถูกต้องควรเป็นข้อพิจารณาอันดับ 1 ของคุณ
ฉันคิดว่าโดยไม่คำนึงถึงความแตกต่าง (ซึ่งทุกคนชี้ให้เห็นว่าการลอยตัวใช้พื้นที่น้อยลงและโดยทั่วไปเร็วกว่า) ... มีใครเคยประสบปัญหาด้านประสิทธิภาพโดยใช้ double หรือไม่? ฉันบอกว่าใช้ double ... และถ้าคุณตัดสินใจในภายหลังว่า "ว้าวนี่ช้าจริงๆ" ... หาคอขวดด้านประสิทธิภาพของคุณ (ซึ่งอาจไม่ใช่ความจริงที่คุณใช้ double) จากนั้นหากคุณยังคงช้าเกินไปให้ดูว่าคุณสามารถสละความแม่นยำและใช้การลอยได้ที่ไหน
ความแตกต่างหลักระหว่าง float และ double คือความแม่นยำ วิกิพีเดียมีข้อมูลเพิ่มเติมเกี่ยวกับ ความแม่นยำเดี่ยว (float) และแม่นยำคู่
ขึ้นอยู่กับ CPU เป็นอย่างมากการแลกเปลี่ยนที่ชัดเจนที่สุดคือระหว่างความแม่นยำและหน่วยความจำ ด้วยแรม GB หน่วยความจำไม่ใช่ปัญหามากนักดังนั้นจึงควรใช้โดยทั่วไปดีกว่าdouble
s
สำหรับประสิทธิภาพนั้นขึ้นอยู่กับ CPU เป็นอย่างมาก float
s มักจะได้รับประสิทธิภาพที่ดีกว่าdouble
s บนเครื่อง 32 บิต ใน 64 บิตdouble
บางครั้งจะเร็วกว่าเนื่องจากเป็นขนาดดั้งเดิม (โดยปกติ) อย่างไรก็ตามสิ่งที่สำคัญมากกว่าประเภทข้อมูลที่คุณเลือกคือคุณสามารถใช้ประโยชน์จากคำแนะนำ SIMD บนโปรเซสเซอร์ของคุณได้หรือไม่
double มีความแม่นยำสูงกว่าในขณะที่การลอยตัวใช้หน่วยความจำน้อยกว่าและเร็วกว่า โดยทั่วไปคุณควรใช้ float เว้นแต่คุณจะมีกรณีที่ไม่แม่นยำเพียงพอ