ฉันคิดว่าabs
และมีพฤติกรรมที่แตกต่างกันเมื่อใช้fabs
math.h
แต่เมื่อฉันใช้เพียงcmath
และstd::abs
ฉันต้องใช้std::fabs
หรือfabs
? หรือไม่ได้กำหนดไว้?
ฉันคิดว่าabs
และมีพฤติกรรมที่แตกต่างกันเมื่อใช้fabs
math.h
แต่เมื่อฉันใช้เพียงcmath
และstd::abs
ฉันต้องใช้std::fabs
หรือfabs
? หรือไม่ได้กำหนดไว้?
คำตอบ:
ใน C ++ ก็เพียงพอเสมอที่จะใช้std::abs
; มันมากเกินไปสำหรับประเภทตัวเลขทั้งหมด
ใน C abs
ใช้ได้เฉพาะกับจำนวนเต็มและคุณต้องการfabs
ค่าทศนิยม สิ่งเหล่านี้มีอยู่ใน C ++ (พร้อมกับไลบรารี C ทั้งหมด) แต่ไม่จำเป็นต้องใช้
int
รุ่นจากห้องสมุด C มี overloads สำหรับlong
, float
, และdouble
long double
ข้อ 26.2.7 ยังกำหนดโอเวอร์โหลดสำหรับcomplex
.
std::
และเพิ่งใช้abs
รหัสของคุณจะทำงานได้ตามที่คาดไว้บน windows แต่จะใช้int
เวอร์ชันบน linux ซึ่งอาจแก้ไขจุดบกพร่องได้ยากอย่างไม่น่าเชื่อ
ยังคงfabs
ใช้ได้สำหรับdouble
และfloat
อาร์กิวเมนต์ ฉันชอบสิ่งนี้เพราะมันช่วยให้มั่นใจได้ว่าถ้าฉันถอดstd::
ไฟล์abs
พฤติกรรมนั้นจะยังคงเหมือนเดิมสำหรับอินพุตจุดลอยตัว
ฉันใช้เวลาเพียง 10 นาทีในการแก้ไขปัญหานี้เนื่องจากความผิดพลาดของฉันเองในการใช้abs
แทนstd::abs
ไฟล์. ฉันเดาว่าusing namespace std;
จะอนุมานstd::abs
แต่ไม่เป็นเช่นนั้นและใช้เวอร์ชัน C แทน
อย่างไรก็ตามฉันเชื่อว่ามันเป็นการดีที่จะใช้fabs
แทนabs
อินพุตจุดลอยตัวเป็นวิธีการบันทึกความตั้งใจของคุณอย่างชัดเจน
std::abs
ดูเหมือนว่าจะมีการเรียกใช้งานมากเกินไป(ไม่ใช่รุ่น C abs
) เมื่อโทรabs
ตราบเท่าที่using namespace std;
มีการอธิบายไว้ที่ จุดเริ่มต้น. ฉันไม่รู้ว่านี่เป็นคอมไพเลอร์เฉพาะหรือไม่
มีอีกเหตุผลหนึ่งที่แนะนำstd::fabs
สำหรับอินพุตทศนิยมอย่างชัดเจน
หากคุณลืมใส่ <cmath> คุณstd::abs(my_float_num)
สามารถใช้std::abs(int)
แทนstd::abs(float)
ได้ มันยากที่จะสังเกตเห็น
"abs" และ "fabs" จะเหมือนกันสำหรับประเภทโฟลต C ++ เท่านั้นเมื่อสามารถแปลได้โดยไม่มีข้อความโอเวอร์โหลดที่คลุมเครือ
ฉันใช้ g ++ (g ++ - 7) ร่วมกับการใช้เทมเพลตและโดยเฉพาะอย่างยิ่งเมื่อใช้ mpreal มีบางกรณีที่มีข้อความ "คลุมเครือเกิน"abs(static_cast<T>(x))
ไม่ได้แก้ปัญหานั้นเสมอไป เมื่อหน้าท้องไม่ชัดเจนมีโอกาสที่ fabs จะทำงานตามที่คาดไว้ สำหรับ sqrt ฉันไม่พบการหลบหนีง่ายๆเช่นนี้
ตั้งแต่สัปดาห์ที่ผ่านมาฉันกำลังดิ้นรนอย่างหนักกับ C ++ "ไม่ใช่ปัญหาที่มีอยู่" ฉันกำลังอัปเดตโปรแกรม C ++ เก่าเป็น C ++ 14 เพื่อให้ใช้งานเทมเพลตได้มากขึ้นและดีขึ้นกว่าเดิม บ่อยครั้งที่พารามิเตอร์เทมเพลตเดียวกันอาจเป็นโฟลตมาตรฐานหรือประเภทที่ซับซ้อนหรือประเภทคลาสก็ได้ เหตุใด long double จึงดูสมเหตุสมผลกว่าประเภทอื่น ๆ ทั้งหมดใช้งานได้และฉันเคยรวม mpreal มาก่อน จากนั้นฉันก็ตั้งค่าประเภทการลอยเริ่มต้นเป็น mpreal และมีข้อผิดพลาดทางไวยากรณ์มากมาย นั่นทำให้โอเวอร์โหลดที่คลุมเครือหลายพันรายการเช่นสำหรับ abs และ sqrt โดยร้องไห้หาวิธีแก้ปัญหาที่แตกต่างกัน บางคนต้องการฟังก์ชันช่วยเหลือมากเกินไป แต่อยู่นอกเทมเพลต ต้องแทนที่การใช้งาน 0.0L และ 1.0L ทีละพันครั้งด้วยประเภทค่าคงที่ที่แน่นอนโดยใช้ Zero หรือ One หรือ type_cast - นิยามการแปลงอัตโนมัติเป็นไปไม่ได้เนื่องจากความไม่ชัดเจน
จนถึงเดือนพฤษภาคมฉันพบว่าการแปลงโดยนัยที่มีอยู่นั้นดีมาก แต่ง่ายกว่ามากมันจะไม่มีเลยและมีค่าคงที่ประเภทบันทึกด้วย type_casts ที่ปลอดภัยเป็นค่าคงที่มาตรฐานอื่น ๆ