มีวิธีมาตรฐานและ / หรือแบบพกพาในการแทนค่าลบที่เล็กที่สุด (เช่นการใช้อินฟินิตี้เชิงลบ) ในโปรแกรม C (++) หรือไม่?
DBL_MIN ใน float.h เป็นจำนวนบวกที่น้อยที่สุด
มีวิธีมาตรฐานและ / หรือแบบพกพาในการแทนค่าลบที่เล็กที่สุด (เช่นการใช้อินฟินิตี้เชิงลบ) ในโปรแกรม C (++) หรือไม่?
DBL_MIN ใน float.h เป็นจำนวนบวกที่น้อยที่สุด
คำตอบ:
-DBL_MAX
ใน ANSI Cซึ่งกำหนดไว้ใน float.h.
-DBL_MAX
ให้เป็นตัวแทนได้อย่างแน่นอนดังนั้นหากฮาร์ดแวร์ FP ไม่สามารถทำได้การใช้งานก็ต้องแก้ไข ดูแบบจำลองจุดลอยตัวใน5.2.4.2.2 ลักษณะของประเภทลอย <float.h> p2ของ C99 (อาจถูกย้ายไปที่อื่นตั้งแต่นั้นมา)
DBL_MAX
เท่ากับ (1 - b ^ −p) b ^ e_max ซึ่งแสดงได้อย่างแน่นอนค่า จำกัด ที่เป็นลบส่วนใหญ่จะเท่ากับ - (1 - b ^ −p) b ^ e_max และเนื่องจากเป็นเช่น-DBL_MAX
นั้นการปฏิเสธDBL_MAX
จึงไม่สามารถทำให้เกิดข้อผิดพลาดในการปัดเศษได้
ตัวเลขจุดลอยตัว (IEEE 754) เป็นแบบสมมาตรดังนั้นหากคุณสามารถแทนค่าที่ยิ่งใหญ่ที่สุด ( DBL_MAX
หรือnumeric_limits<double>::max()
) ได้ให้นำหน้าเครื่องหมายลบ
แล้วก็เป็นวิธีที่ยอดเยี่ยม:
double f;
(*((long long*)&f))= ~(1LL<<52);
ในภาษา C ให้ใช้
#include <float.h>
const double lowest_double = -DBL_MAX;
ใน C ++ pre-11 ให้ใช้
#include <limits>
const double lowest_double = -std::numeric_limits<double>::max();
ใน C ++ 11 ขึ้นไปให้ใช้
#include <limits>
constexpr double lowest_double = std::numeric_limits<double>::lowest();
min()
ฟังก์ชั่นก่อน C ++ 11? หรือว่าเป็นมูลค่าที่แตกต่างจาก-max()
? en.cppreference.com/w/cpp/types/numeric_limits
min
ได้รับค่าบวกที่น้อยที่สุดในขนาดและlowest
ค่าลบที่ใหญ่ที่สุดในขนาด ใช่มันแย่มาก ยินดีต้อนรับสู่โลกที่ยอดเยี่ยมของ c ++ :-P
ห้องสมุดมาตรฐาน
float.h
. limits.h
สำหรับจำนวนเต็ม
ลองสิ่งนี้:
-1 * numeric_limits<double>::max()
อ้างอิง: numeric_limits
คลาสนี้มีความเชี่ยวชาญสำหรับประเภทพื้นฐานแต่ละประเภทโดยสมาชิกจะส่งคืนหรือตั้งค่าเป็นค่าต่างๆที่กำหนดคุณสมบัติที่ประเภทมีในแพลตฟอร์มเฉพาะที่คอมไพล์
-numeric_limits<double>::max()
?
-1 * ...
เพื่อให้ชัดเจนขึ้น
คุณกำลังมองหาค่าอินฟินิตี้ที่แท้จริงหรือค่า จำกัด ขั้นต่ำ? หากเป็นแบบเดิมให้ใช้
-numeric_limits<double>::infinity()
ซึ่งใช้ได้เฉพาะเมื่อ
numeric_limits<double>::has_infinity
มิฉะนั้นคุณควรใช้
numeric_limits<double>::lowest()
ซึ่งแนะนำใน C ++ 11
หากlowest()
ไม่สามารถใช้งานได้คุณสามารถถอยกลับไปที่
-numeric_limits<double>::max()
ซึ่งอาจแตกต่างจากโดยlowest()
หลักการ แต่โดยปกติแล้วไม่ได้ใช้ในทางปฏิบัติ
-numeric_limits<double>::max()
แม้ว่าจะใช้งานได้จริง แต่ก็ไม่สามารถพกพาได้อย่างสมบูรณ์ตามทฤษฎี
จาก C ++ 11 คุณสามารถใช้ numeric_limits<double>::lowest()
. ตามมาตรฐานจะส่งคืนสิ่งที่คุณต้องการ:
ค่า จำกัด x ดังกล่าวว่าไม่มีค่า Y จำกัด อื่น ๆ
y < x
ที่ มีความหมายสำหรับเฉพาะทุกที่is_bounded != false
มีคำตอบมากมายเกิด-std::numeric_limits<double>::max()
ขึ้น
โชคดีที่พวกเขาจะทำงานได้ดีในกรณีส่วนใหญ่ รูปแบบการเข้ารหัสจุดลอยตัวจะย่อยสลายตัวเลขในแมนทิสซาและเลขชี้กำลังและส่วนใหญ่ (เช่นIEEE-754 ที่เป็นที่นิยม) ใช้บิตเครื่องหมายที่แตกต่างกันซึ่งไม่ได้เป็นของแมนทิสซา สิ่งนี้ช่วยให้สามารถเปลี่ยนค่าบวกที่ใหญ่ที่สุดในค่าลบที่เล็กที่สุดเพียงแค่พลิกเครื่องหมาย:
มาตรฐานไม่ได้กำหนดมาตรฐานจุดลอยตัวใด ๆ
ผมยอมรับว่าข้อโต้แย้งของฉันเป็นทฤษฎีนิด ๆ หน่อย ๆ แต่คิดว่าบางชงคอมไพเลอร์ excentric จะใช้การเข้ารหัสรูปแบบการปฏิวัติกับ mantissa เข้ารหัสในรูปแบบของบางส่วนเติมเต็มสอง การเข้ารหัสส่วนเสริมของ Two ไม่สมมาตร ตัวอย่างเช่นถ่าน 8 บิตที่ลงชื่อแล้วค่าบวกสูงสุดคือ 127 แต่ค่าลบต่ำสุดคือ -128 ดังนั้นเราจึงสามารถจินตนาการได้ว่าการเข้ารหัสจุดลอยตัวบางอย่างแสดงพฤติกรรมไม่สมมาตรที่คล้ายกัน
ฉันไม่ได้ตระหนักถึงการเข้ารหัสรูปแบบใด ๆ เช่นนั้น แต่ประเด็นก็คือว่ามาตรฐานไม่ได้รับประกันว่าพลิกป้ายถัวเฉลี่ยผลที่ตั้งใจไว้ ดังนั้นคำตอบยอดนิยมนี้ (ขออภัย!) ไม่สามารถถือเป็นโซลูชันมาตรฐานแบบพกพาได้อย่างสมบูรณ์! / * อย่างน้อยก็ไม่ใช่ถ้าคุณไม่ยืนยันว่าnumeric_limits<double>::is_iec559
เป็นความจริง * /
คำถามเดิมเกี่ยวข้องกับความไม่มีที่สิ้นสุด ทำไมไม่ใช้
#define Infinity ((double)(42 / 0.0))
ตามนิยามของ IEEE? แน่นอนคุณสามารถลบล้างสิ่งนั้นได้
numeric_limits<double>::has_infinity && ! numeric_limits<double>::traps
มีวิธีมาตรฐานและ / หรือแบบพกพาในการแทนค่าลบที่เล็กที่สุด (เช่นการใช้อินฟินิตี้เชิงลบ) ในโปรแกรม C (++) หรือไม่?
แนวทาง C
การใช้งานหลายคนสนับสนุน +/- อนันต์ดังนั้นเชิงลบมากที่สุดค่าdouble
-INFINITY
#include <math.h>
double most_negative = -INFINITY;
มีแบบมาตรฐานและ / หรือแบบพกพา .... ?
ตอนนี้เราต้องพิจารณากรณีอื่น ๆ ด้วย:
เพียงแค่-DBL_MAX
.
ผมคาดว่าในกรณีนี้ OP -DBL_MAX
ต้องการ
DBL_MAX
ปกติมากขึ้นในขนาดกว่านี่เป็นกรณีที่ผิดปกติซึ่งน่าจะอยู่นอกความกังวลของ OP เมื่อdouble
ใดที่ถูกเข้ารหัสเป็นคู่ของจุดลอยตัวเพื่อให้ได้ช่วง / ระยะถอยที่ต้องการ (ดูdouble-double ) จะมีค่าปกติ สูงสุดdouble
และอาจเป็นค่าปกติที่มากกว่า ฉันเคยเห็นการถกเถียงกันว่าDBL_MAX
ควรอ้างถึงสิ่งปกติที่ยิ่งใหญ่ที่สุดของสิ่งที่ยิ่งใหญ่ที่สุดของทั้งสองอย่าง
โชคดีที่วิธีการจับคู่นี้มักมี -infinity -INFINITY
ดังนั้นส่วนใหญ่ยังคงเป็นค่าลบ
เพื่อความสะดวกในการพกพามากขึ้นโค้ดสามารถลงไปตามเส้นทางได้
// HUGE_VAL is designed to be infinity or DBL_MAX (when infinites are not implemented)
// .. yet is problematic with unsigned infinity.
double most_negative1 = -HUGE_VAL;
// Fairly portable, unless system does not understand "INF"
double most_negative2 = strtod("-INF", (char **) NULL);
// Pragmatic
double most_negative3 = strtod("-1.0e999999999", (char **) NULL);
// Somewhat time-consuming
double most_negative4 = pow(-DBL_MAX, 0xFFFF /* odd value */);
// My suggestion
double most_negative5 = (-DBL_MAX)*DBL_MAX;
หากคุณไม่ได้เปิดใช้งานข้อยกเว้นการลอยตัว (ซึ่งคุณไม่ควรใช้) คุณสามารถพูดได้ง่ายๆว่า:
double neg_inf = -1/0.0;
สิ่งนี้ให้ผลลบอินฟินิตี้ หากคุณต้องการลูกลอยคุณสามารถส่งผลลัพธ์ได้
float neg_inf = (float)-1/0.0;
หรือใช้เลขคณิตที่มีความแม่นยำเดียว
float neg_inf = -1.0f/0.0f;
ผลลัพธ์จะเหมือนกันเสมอมีการแทนค่าอินฟินิตี้เชิงลบเพียงค่าเดียวในทั้งความแม่นยำเดี่ยวและคู่และจะแปลงซึ่งกันและกันตามที่คุณคาดหวัง
-INFINITY
neg_inf
จะเริ่มต้นกับค่าคงที่ คอมไพเลอร์จะดูแลการคำนวณinf
ค่า และเมื่อคุณใช้เป็นค่า null ในการคำนวณค่าสูงสุดการวนซ้ำครั้งแรกโดยทั่วไปจะเขียนทับด้วยค่าที่มากกว่า คือประสิทธิภาพแทบจะไม่มีปัญหา และ OP ถามเป็นพิเศษเกี่ยวกับ "เช่นการใช้อินฟินิตี้เชิงลบ" และ-inf
เป็นคำตอบเดียวที่ถูกต้องสำหรับเรื่องนี้ คุณได้ลดคะแนนคำตอบที่ถูกต้องและมีประโยชน์