เมื่อเปรียบเทียบค่าทศนิยมเพื่อความเท่าเทียมมีสองวิธีที่แตกต่างกัน:
NaN
จะไม่เท่ากับตัวเองซึ่งตรงกับมาตรฐาน IEEE 754สเปคNaN
มีความเท่าเทียมกับตัวเองซึ่งให้คุณสมบัติทางคณิตศาสตร์ของReflexivityซึ่งเป็นสิ่งจำเป็นต่อความหมายของความสัมพันธ์ที่เท่าเทียมกัน
สร้างขึ้นใน IEEE ลอยชนิดจุดใน C # ( float
และdouble
) ปฏิบัติตามมาตรฐาน IEEE ความหมายสำหรับ==
และ!=
(และผู้ประกอบการเชิงสัมพันธ์เช่น<
) แต่ให้มั่นใจ reflexivity สำหรับobject.Equals
, IEquatable<T>.Equals
(และCompareTo
)
ตอนนี้พิจารณาห้องสมุดที่ให้ structs เวกเตอร์ที่ด้านบนของ/float
double
ประเภทเวกเตอร์ดังกล่าวจะเกิน==
/ !=
และแทนที่/object.Equals
IEquatable<T>.Equals
สิ่งที่ทุกคนเห็นพ้องต้องกันคือ==
/ !=
ควรทำตามความหมายของ IEEE คำถามคือห้องสมุดควรใช้Equals
วิธีการ (ซึ่งแยกจากตัวดำเนินการความเสมอภาค) ในวิธีที่สะท้อนกลับหรือในวิธีที่ตรงกับความหมายของ IEEE
อาร์กิวเมนต์สำหรับการใช้ความหมายของ IEEE สำหรับEquals
:
- เป็นไปตาม IEEE 754
มันเร็วกว่า (อาจมาก) เพราะสามารถใช้ประโยชน์จากคำสั่ง SIMD ได้
ฉันได้ถามคำถามแยกต่างหากเกี่ยวกับสแต็คโอเวอร์โฟลว์เกี่ยวกับวิธีที่คุณแสดงความเท่าเทียมสะท้อนกลับโดยใช้คำสั่ง SIMD และผลกระทบต่อประสิทธิภาพการทำงานของพวกเขา: คำแนะนำ SIMD สำหรับการเปรียบเทียบความเท่าเทียมกันของจุดลอยตัว
อัปเดต:ดูเหมือนว่าเป็นไปได้ที่จะใช้ความเท่าเทียมแบบสะท้อนได้อย่างมีประสิทธิภาพโดยใช้คำสั่ง SIMD สามคำ
เอกสารสำหรับ
Equals
ไม่จำเป็นต้องมีการสะท้อนกลับเมื่อเกี่ยวข้องกับจุดลอยตัว:ข้อความต่อไปนี้ต้องเป็นจริงสำหรับการใช้งานทั้งหมดของวิธีการ Equals (Object) ในรายการ
x
,y
และz
แทนการอ้างอิงวัตถุที่ไม่เป็นโมฆะx.Equals(x)
ผลตอบแทนtrue
ยกเว้นในกรณีที่เกี่ยวข้องกับประเภทจุดลอย ดูที่ ISO / IEC / IEEE 60559: 2011, เทคโนโลยีสารสนเทศ - ระบบไมโครโปรเซสเซอร์ - เลขทศนิยมหากคุณกำลังใช้โฟลทเป็นคีย์พจนานุกรมคุณกำลังใช้ชีวิตอยู่ในสภาพบาปและไม่ควรคาดหวังพฤติกรรมที่มีสติ
อาร์กิวเมนต์สำหรับการสะท้อนกลับ:
มันเป็นเรื่องที่สอดคล้องกับประเภทที่มีอยู่รวมทั้ง
Single
,Double
, และTuple
System.Numerics.Complex
ฉันไม่รู้แบบอย่างใด ๆ ใน BCL ที่
Equals
ติดตาม IEEE แทนที่จะสะท้อนกลับ เคาน์เตอร์ตัวอย่าง ได้แก่Single
,Double
, และTuple
System.Numerics.Complex
Equals
ส่วนใหญ่จะใช้โดยคอนเทนเนอร์และอัลกอริทึมการค้นหาซึ่งขึ้นอยู่กับการสะท้อนกลับ สำหรับอัลกอริธึมเหล่านี้ประสิทธิภาพที่เพิ่มขึ้นนั้นไม่เกี่ยวข้องหากป้องกันไม่ให้ทำงานได้ อย่าเสียสละความถูกต้องในการแสดง- จะแบ่งทุกชุดกัญชาและพจนานุกรม
Contains
,Find
,IndexOf
คอลเลกชันต่างๆ / LINQ การดำเนินงานชุด LINQ based (Union
,Except
ฯลฯ ) หากข้อมูลที่มีNaN
ค่า โค้ดที่ทำการคำนวณจริงที่ยอมรับได้ในความหมายของ IEEE มักใช้กับรูปแบบที่เป็นรูปธรรมและใช้
==
/!=
(หรือการเปรียบเทียบ epsilon ที่มีแนวโน้มมากกว่า)ขณะนี้คุณไม่สามารถเขียนการคำนวณประสิทธิภาพสูงโดยใช้ generics เนื่องจากคุณต้องการการดำเนินการทางคณิตศาสตร์สำหรับสิ่งนั้น แต่สิ่งเหล่านี้ไม่สามารถใช้ได้ผ่านทางอินเตอร์เฟส / วิธีการเสมือน
ดังนั้น
Equals
วิธีที่ช้ากว่าจะไม่ส่งผลกระทบต่อรหัสประสิทธิภาพสูงที่สุดเป็นไปได้ที่จะให้
IeeeEquals
วิธีการหรือIeeeEqualityComparer<T>
กรณีที่คุณต้องการความหมายของ IEEE หรือคุณต้องการประสิทธิภาพที่เหนือกว่า
ในความคิดของฉันข้อโต้แย้งเหล่านี้สนับสนุนการใช้งานแบบสะท้อนกลับอย่างยิ่ง
ทีม CoreFX ของ Microsoft วางแผนที่จะแนะนำประเภทเวกเตอร์ดังกล่าวใน. NET ซึ่งแตกต่างจากฉันพวกเขาชอบโซลูชัน IEEEส่วนใหญ่เนื่องจากข้อได้เปรียบด้านประสิทธิภาพ เนื่องจากการตัดสินใจดังกล่าวจะไม่เปลี่ยนแปลงหลังจากการเปิดตัวครั้งสุดท้ายฉันต้องการได้รับคำติชมจากชุมชนในสิ่งที่ฉันเชื่อว่าเป็นความผิดพลาดครั้งใหญ่
float
/ double
และประเภทอื่น ๆ==
และEquals
แตกต่างกันไปแล้ว ผมคิดว่าไม่สอดคล้องกับชนิดที่มีอยู่จะทำให้เกิดความสับสนมากยิ่งขึ้นกว่าที่ไม่สอดคล้องกันระหว่าง==
และEquals
คุณยังจะต้องจัดการกับประเภทอื่น ๆ 2) อัลกอริธึมทั่วไป / คอลเลกชันทั่วไปใช้Equals
และพึ่งพาการสะท้อนกลับของฟังก์ชั่น (LINQ และพจนานุกรม) ในขณะที่อัลกอริธึมจุดลอยตัวที่เป็นรูปธรรมมักจะใช้ใน==
ที่ที่พวกเขาได้รับความหมาย IEEE
Vector<float>
เป็น "สัตว์" ที่แตกต่างกว่าที่เรียบง่ายหรือfloat
double
จากมาตรการดังกล่าวฉันไม่เห็นเหตุผลEquals
หรือ==
ผู้ปฏิบัติงานปฏิบัติตามมาตรฐานของพวกเขา คุณพูดกับตัวเองว่า: "ถ้าคุณกำลังลอยเป็นกุญแจพจนานุกรมที่คุณใช้ชีวิตอยู่ในสภาพบาปและไม่ควรคาดหวังพฤติกรรมที่มีสติ" หากมีใครที่จะเก็บไว้NaN
ในพจนานุกรมก็เป็นความผิดของตัวเองสำหรับการใช้การปฏิบัติที่น่ากลัว ฉันแทบจะไม่คิดว่าทีม CoreFX ไม่ได้คิดอย่างนั้น ฉันจะไปด้วยReflexiveEquals
หรือคล้ายกันเพียงเพื่อประสิทธิภาพ
==
และEquals
จะให้ผลลัพธ์ที่แตกต่าง โปรแกรมเมอร์จำนวนมากถือว่าพวกเขาเป็นและทำในสิ่งเดียวกัน นอกจากนี้ - โดยทั่วไปการใช้งานของตัวดำเนินการความเสมอภาคจะเรียกใช้Equals
เมธอด คุณยังเป็นที่ถกเถียงกันว่าหนึ่งอาจรวมถึงIeeeEquals
แต่อย่างหนึ่งอาจทำวิธีอื่น ๆ และรวมถึงReflexiveEquals
-methodVector<float>
ชนิดอาจจะใช้ในหลายประสิทธิภาพการใช้งานที่มีความสำคัญและควรได้รับการปรับให้เหมาะสมตาม