ฉันควรใช้ fabs เมื่อใดและเมื่อใดจึงเพียงพอที่จะใช้ std :: abs


100

ฉันคิดว่าabsและมีพฤติกรรมที่แตกต่างกันเมื่อใช้fabs math.hแต่เมื่อฉันใช้เพียงcmathและstd::absฉันต้องใช้std::fabsหรือfabs? หรือไม่ได้กำหนดไว้?

คำตอบ:


124

ใน C ++ ก็เพียงพอเสมอที่จะใช้std::abs; มันมากเกินไปสำหรับประเภทตัวเลขทั้งหมด

ใน C absใช้ได้เฉพาะกับจำนวนเต็มและคุณต้องการfabsค่าทศนิยม สิ่งเหล่านี้มีอยู่ใน C ++ (พร้อมกับไลบรารี C ทั้งหมด) แต่ไม่จำเป็นต้องใช้


เป็นเช่นนี้ในทุกแพลตฟอร์มหรือไม่ Esp. Windows และ Mac OS X? หรืออย่างน้อยก็อยู่ในมาตรฐาน C ++?
คณิตศาสตร์

3
@brubelsabs: ใช่ ไม่จำเป็นต้องมีฟังก์ชัน fabs แยกต่างหากใน C ++ เนื่องจาก C ++ มีฟังก์ชันโอเวอร์โหลด (abs สามารถกำหนดได้หลายประเภทและอยู่ใน C ++) ยังได้รับการการันตีด้วยมาตรฐาน แน่นอนว่าหากคุณค้นหาคอมไพเลอร์ที่ล้าสมัยมากกว่า 10 ปีคุณอาจพบคอมไพเลอร์ที่ไม่รองรับ
stinky472

1
มันอยู่ใน c ++ มาตรฐานจึงเป็นกรณีที่เกี่ยวกับทุกแพลตฟอร์มกับคอมไพเลอร์ที่ดีรวมทั้ง Windows และ Mac OS X 26.5 ข้อกล่าวว่านอกเหนือไปจากintรุ่นจากห้องสมุด C มี overloads สำหรับlong, float, และdouble long doubleข้อ 26.2.7 ยังกำหนดโอเวอร์โหลดสำหรับcomplex.
Mike Seymour

6
หากคุณลืมstd::และเพิ่งใช้absรหัสของคุณจะทำงานได้ตามที่คาดไว้บน windows แต่จะใช้intเวอร์ชันบน linux ซึ่งอาจแก้ไขจุดบกพร่องได้ยากอย่างไม่น่าเชื่อ
Adversus

" ประเภทตัวเลขทั้งหมด " [จำเป็นต้องอ้างอิง] ฉันสามารถดู int, long, long, std :: intmax_t, float, double, long double ไม่มีเวอร์ชันสั้นหรือถ่าน (หรือเวอร์ชันที่ไม่ได้ลงชื่อ) ให้ฉันเห็น
user673679

23

ยังคงfabsใช้ได้สำหรับdoubleและfloatอาร์กิวเมนต์ ฉันชอบสิ่งนี้เพราะมันช่วยให้มั่นใจได้ว่าถ้าฉันถอดstd::ไฟล์absพฤติกรรมนั้นจะยังคงเหมือนเดิมสำหรับอินพุตจุดลอยตัว

ฉันใช้เวลาเพียง 10 นาทีในการแก้ไขปัญหานี้เนื่องจากความผิดพลาดของฉันเองในการใช้absแทนstd::absไฟล์. ฉันเดาว่าusing namespace std;จะอนุมานstd::absแต่ไม่เป็นเช่นนั้นและใช้เวอร์ชัน C แทน

อย่างไรก็ตามฉันเชื่อว่ามันเป็นการดีที่จะใช้fabsแทนabsอินพุตจุดลอยตัวเป็นวิธีการบันทึกความตั้งใจของคุณอย่างชัดเจน


2
แปลก. การโทรของคุณน่าจะคลุมเครือ (และเป็นข้อผิดพลาด) ใช่ไหม?
นิค

คุณไม่ควรใช้ fabsf เพื่อลอย? ดังนั้นฉันไม่คิดว่ามันเหมือนกัน
นิค

ระวัง Android NDK g ++ มันยังยกให้ฟังก์ชัน c abs () แทน std :: abs () ในคอมไพเลอร์ Visual Studio c ++ อย่างไรก็ตาม abs จะชี้ไปที่ std :: abs () เสมอ
southerton

@ นิกฉันคิดว่าฉันเห็นด้วยกับคุณ: ดูเหมือนว่าฉันจะไม่เข้าใจพฤติกรรมของอลันทัวริงเช่นสำหรับฉันแล้วstd::absดูเหมือนว่าจะมีการเรียกใช้งานมากเกินไป(ไม่ใช่รุ่น C abs) เมื่อโทรabsตราบเท่าที่using namespace std;มีการอธิบายไว้ที่ จุดเริ่มต้น. ฉันไม่รู้ว่านี่เป็นคอมไพเลอร์เฉพาะหรือไม่
MaviPranav

@ นิคไม่ใช่ข้อผิดพลาดเนื่องจากมีชื่อฟังก์ชันที่ตรงกัน เป็นการกำหนดการนำไปใช้งานที่จะเลือก
Pato Sandaña

11

มีอีกเหตุผลหนึ่งที่แนะนำstd::fabsสำหรับอินพุตทศนิยมอย่างชัดเจน

หากคุณลืมใส่ <cmath> คุณstd::abs(my_float_num)สามารถใช้std::abs(int)แทนstd::abs(float)ได้ มันยากที่จะสังเกตเห็น


1

"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 ที่ปลอดภัยเป็นค่าคงที่มาตรฐานอื่น ๆ

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