“ f” หลังตัวเลข


102

อะไรfหลังจากตัวเลขที่บ่งบอก? นี่มาจาก C หรือ Objective-C? มีความแตกต่างในการไม่เพิ่มสิ่งนี้เป็นจำนวนคงที่หรือไม่?

CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);

คุณอธิบายได้ไหมว่าทำไมฉันถึงไม่เขียน:

CGRect frame = CGRectMake(0, 0, 320, 50);

คำตอบ:


88
CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);

ใช้ค่าคงที่ลอย (ค่าคงที่ 0.0 มักจะประกาศสองเท่าใน Objective-C การใส่ f ไว้ท้าย - 0.0f - ประกาศค่าคงที่เป็นทศนิยม (32 บิต))

CGRect frame = CGRectMake(0, 0, 320, 50);

ใช้ ints ซึ่งจะถูกแปลงเป็นลอยโดยอัตโนมัติ

ในกรณีนี้ไม่มีความแตกต่าง (ในทางปฏิบัติ) ระหว่างทั้งสอง


24
ในทางทฤษฎีคอมไพเลอร์อาจไม่ฉลาดพอที่จะแปลงให้ลอยในเวลาคอมไพล์และจะทำให้การดำเนินการช้าลงด้วยการแปลง int-> สี่รายการ (ซึ่งเป็นหนึ่งในการร่ายที่ช้าที่สุด) แม้ว่าในกรณีนี้จะแทบไม่มีความสำคัญ แต่การระบุ f ให้ถูกต้องจะดีกว่าเสมอหากจำเป็น: ในนิพจน์ค่าคงที่โดยไม่มีตัวระบุที่ถูกต้องอาจบังคับให้นิพจน์ทั้งหมดถูกแปลงเป็นสองเท่าและหากอยู่ในวงที่แน่นประสิทธิภาพการตีอาจเป็นได้ เห็นได้ชัด
Matteo Italia

60

หากมีข้อสงสัยให้ตรวจสอบเอาต์พุตของแอสเซมเบลอร์ เช่นเขียนตัวอย่างเล็ก ๆ น้อย ๆ เช่นนี้

#import <Cocoa/Cocoa.h>

void test() {
  CGRect r = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);
  NSLog(@"%f", r.size.width);
}

จากนั้นคอมไพล์ไปยังแอสเซมเบลอร์ด้วย-Sตัวเลือก

gcc -S test.m

บันทึกเอาต์พุตแอสเซมเบลอร์ในtest.sไฟล์และลบออก.0fจากค่าคงที่และทำซ้ำคำสั่งคอมไพล์ จากนั้นทำสิ่งdiffใหม่test.sและก่อนหน้านี้ คิดว่าควรแสดงให้เห็นว่ามีความแตกต่างจริงหรือไม่ ฉันคิดว่าหลายคนมีวิสัยทัศน์ในสิ่งที่พวกเขาคิดว่าคอมไพเลอร์ทำ แต่ในตอนท้ายของวันเราควรรู้วิธีตรวจสอบทฤษฎีใด ๆ


11
-Oเอาท์พุทเปิดออกมาจะเหมือนกันสำหรับผมแม้จะไม่มีการใด ๆ ฉันใช้ i686-apple-darwin10-gcc-4.2.1 (GCC)
kizzx2

2
ฉันลองใช้ตัวอย่างข้างต้นกับ LLVM เวอร์ชัน 7.0.0 (clang-700.0.65) x86_64-apple-darwin15.0.0 และไฟล์. out ก็เหมือนกันเช่นกัน
นิค

43

บางครั้งก็มีความแตกต่าง

float f = 0.3; /* OK, throw away bits to convert 0.3 from double to float */
assert ( f == 0.3 ); /* not OK, f is converted from float to double
   and the value of 0.3 depends on how many bits you use to represent it. */
assert ( f == 0.3f ); /* OK, comparing two floats, although == is finicky. */

26

มันบอกคอมพิวเตอร์ว่านี่คือตัวเลขทศนิยม (สมมติว่าคุณกำลังพูดถึง c / c ++ ที่นี่) หากไม่มี f หลังตัวเลขจะถือว่าเป็นสองเท่าหรือจำนวนเต็ม (ขึ้นอยู่กับว่ามีทศนิยมหรือไม่)

3.0f -> float
3.0 -> double
3 -> integer

อนุสัญญานี้เป็นส่วนหนึ่งของมาตรฐาน C ++ หรือพบในคอมไพเลอร์?
jxramos

1
เท่าที่ฉันสามารถบอกได้ว่าเป็นส่วนหนึ่งของมาตรฐาน (มีคนแก้ไขฉันถ้าฉันผิด) ข้อมูลอ้างอิงที่เร็วที่สุดที่ฉันสามารถหาได้คือopen-std.org/jtc1/sc22/open/n2356/lex.html#lex.fconแต่อาจมีข้อมูลอ้างอิงที่ทันสมัยกว่าหากคุณต้องการค้นหา
NickLH

5

ทศนิยมตามตัวอักษรในซอร์สโค้ดของคุณจะถูกแยกวิเคราะห์เป็นสองเท่า การกำหนดให้กับตัวแปรที่เป็นประเภท float จะสูญเสียความแม่นยำ แม่นยำมากคุณกำลังทิ้งตัวเลขสำคัญ 7 หลักไป postfix "f" ให้คุณบอกคอมไพเลอร์ว่า: "ฉันรู้ว่าฉันกำลังทำอะไรอยู่นี่คือเจตนาอย่ารบกวนฉันเลย"

โอกาสในการสร้างข้อผิดพลาดนั้นไม่ได้มีขนาดเล็ก โปรแกรมจำนวนมากได้แก้ไขการเปรียบเทียบจุดลอยตัวที่ไม่เหมาะสมหรือสมมติว่า 0.1 เป็นตัวแทนที่แน่นอน


4

สิ่งfที่คุณกำลังพูดถึงอาจหมายถึงการบอกคอมไพเลอร์ว่ามันทำงานกับโฟลต เมื่อคุณละเว้นfมันมักจะแปลเป็นสองเท่า

ทั้งสองเป็นตัวเลขทศนิยม แต่floatใช้บิตน้อยกว่า (จึงเล็กกว่าและแม่นยำน้อยกว่า) มากกว่า a double.


3

มันเป็นสิ่งที่ C - ตัวอักษรทศนิยมมีความแม่นยำสองเท่า (สองเท่า) โดยค่าเริ่มต้น การเพิ่มคำต่อท้าย f ทำให้มีความแม่นยำเดียว (ลอย)

คุณสามารถใช้ ints เพื่อระบุค่าที่นี่และในกรณีนี้จะไม่สร้างความแตกต่าง แต่การใช้ประเภทที่ถูกต้องเป็นนิสัยที่ดีในการทำความเข้าใจโดยทั่วไปความสม่ำเสมอเป็นสิ่งที่ดีและหากคุณต้องการเปลี่ยนค่าเหล่านี้ในภายหลังคุณ จะรู้ได้ทันทีว่าเป็นประเภทใด


2

จาก C. หมายถึงค่าคงที่ตามตัวอักษรลอย คุณสามารถละทั้ง "f" และ ".0" และใช้ ints ในตัวอย่างของคุณได้เนื่องจากการแปลง int โดยปริยายเป็น float


1

เกือบจะแน่นอนว่ามาจาก C และสะท้อนถึงความปรารถนาที่จะใช้ 'float' มากกว่าประเภท 'double' คล้ายกับคำต่อท้ายเช่น L บนตัวเลขเพื่อระบุว่าเป็นจำนวนเต็มยาว คุณสามารถใช้จำนวนเต็มและคอมไพเลอร์จะแปลงอัตโนมัติตามความเหมาะสม (สำหรับสถานการณ์เฉพาะนี้)


0

โดยปกติจะบอกคอมไพลเลอร์ว่าค่าคือ a floatคือจำนวนเต็มทศนิยม ซึ่งหมายความว่ามันสามารถเก็บจำนวนเต็มค่าทศนิยมและ exponentials เช่น1, หรือ0.41.2e+22

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