ทำไมคุณต้องลอย / สองครั้ง?


29

ฉันดูhttp://www.joelonsoftware.com/items/2011/06/27.htmlและหัวเราะเยาะจอน Skeet ตลก ๆ ประมาณ 0.3 ไม่ใช่ 0.3 ฉันเองไม่เคยมีปัญหากับการลอย / ทศนิยม / คู่ แต่ฉันจำได้ว่าฉันเรียนรู้ 6502 เร็วมากและไม่จำเป็นต้องลอยในโปรแกรมส่วนใหญ่ของฉัน ครั้งเดียวที่ฉันใช้มันสำหรับกราฟิกและคณิตศาสตร์ที่ตัวเลขไม่ถูกต้องก็โอเคและผลลัพธ์สำหรับหน้าจอและไม่ถูกเก็บไว้ (ในฐานข้อมูลไฟล์) หรือขึ้นอยู่กับ

คำถามของฉันคือสถานที่ที่คุณมักจะใช้ทุ่น / ทศนิยม / สองครั้งที่ไหน? ดังนั้นฉันรู้ที่จะระวัง gotchas เหล่านี้ ด้วยเงินฉันใช้ longs และเก็บค่าเป็นเปอร์เซ็นต์สำหรับความเร็วของวัตถุในเกมที่ฉันเพิ่ม ints และหาร (หรือ bithift) ค่าเพื่อทราบว่าฉันต้องการย้ายพิกเซลหรือไม่ (ฉันทำการเคลื่อนที่วัตถุใน 6502 วันเราไม่มีการหารหรือลอย แต่มีการเปลี่ยนแปลง)

ดังนั้นฉันส่วนใหญ่อยากรู้อยากเห็น


10
เพราะมันมีความสำคัญมากที่ดอกเบี้ยที่ฉันจ่ายให้กับการจำนองของฉันยังคงอยู่ที่ 12.6 และ doest กลายเป็น 13 เพียงเพราะ 13 เป็นจำนวนรอบที่ดี
Chani

1
"ฉันเรียนรู้ 6502 เร็วมากและไม่ต้องการลอยตัวในโปรแกรมส่วนใหญ่ของฉัน ... สำหรับความเร็วของวัตถุที่ฉันเพิ่ม ints และแบ่งค่าเพื่อทราบว่าจะย้ายพิกเซลหรือไม่" นี่เป็นวิธีที่ผิดปกติอย่างมากในการทำงานเหล่านี้ให้สำเร็จในแนวปฏิบัติที่ทันสมัยยกเว้นการใช้เงินแทนเซ็นต์ยาว
jprete

คอมพิวเตอร์ที่ดีเข้าใจมิลลิมิลลิวินาที
tylermac

1
หรือนอกจากนี้ทำไมต้องใช้ทศนิยมเมื่อเราสามารถใช้เศษส่วนได้
tylermac

6
@Scrooge - แดกดันคุณไม่สามารถแสดง 0.6 ในการลอย
Martin Beckett

คำตอบ:


28

เพราะพวกเขามีเพื่อวัตถุประสงค์ส่วนใหญ่มากขึ้นถูกต้องกว่าจำนวนเต็ม

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

แต่คุณอาจต้องการอธิบายวัตถุที่ช้ามาก ๆ เช่นเข็มชั่วโมงของนาฬิกา เนื่องจากนี่เป็นเรื่องเกี่ยวกับลำดับ 6 ของขนาดที่ช้ากว่าวัตถุกระสุนส่วน ld แรก (10≈) ≈ 20 บิตเป็นศูนย์ซึ่งจะแยกshort intประเภทตั้งแต่เริ่มต้น ตกลงวันนี้เรามีlongทุกที่ที่เรา 12 บิตยังคงสะดวกสบาย แต่ถึงอย่างนั้นความเร็วของนาฬิกาก็จะเท่ากับทศนิยมสี่ตำแหน่งเท่านั้น นั่นไม่ใช่นาฬิกาที่ดีมาก ... แต่มันก็โอเคสำหรับเกม เพียงแค่คุณไม่ต้องการทำให้หยาบมากขึ้นกว่าที่เป็นอยู่แล้ว

... ซึ่งนำไปสู่ปัญหาหากบางวันคุณควรจะแนะนำวัตถุชนิดใหม่ที่เร็วยิ่งขึ้น ไม่มี "headroom" เหลืออยู่

จะเกิดอะไรขึ้นถ้าเราเลือกประเภทลอย ขนาดเท่ากันคือ 32 บิต แต่ตอนนี้คุณมีความแม่นยำ 24 บิตเต็มสำหรับวัตถุทั้งหมด นั่นหมายความว่านาฬิกามีความแม่นยำเพียงพอที่จะซิงค์แบบต่อเนื่องได้นานหลายปี กระสุนไม่มีความแม่นยำสูงกว่า แต่พวกมันจะ "มีชีวิต" สำหรับเศษเสี้ยวของวินาทีเท่านั้นดังนั้นมันจะไร้ประโยชน์อย่างเต็มที่ถ้าพวกมันมี และคุณจะไม่ได้รับปัญหาใด ๆ หากคุณต้องการอธิบายวัตถุที่เร็วยิ่งขึ้น (ทำไมไม่ใช้ความเร็วแสง? ไม่มีปัญหา) หรือวัตถุที่ช้ากว่ามาก แน่นอนว่าคุณไม่จำเป็นต้องมีสิ่งต่าง ๆ ในเกม แต่บางครั้งคุณก็ทำแบบจำลองทางฟิสิกส์

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


จำนวนเต็มที่ถูกต้องสมบูรณ์ ความไม่ถูกต้องขึ้นอยู่กับการคำนวณที่ไม่ถูกต้อง
fjdumont

15
จำนวนเต็มมีความแม่นยำอย่างสมบูรณ์ก็ต่อเมื่อคุณใช้พวกเขาเพื่อแสดงตัวเลขจำนวนเต็ม (ℤ) จริง การแสดงสิ่งอื่นหมายถึงการคำนวณที่ไม่ถูกต้องอย่างแท้จริง ในกรณีเช่นนี้คุณมีความเป็นไปได้สองอย่าง: กำหนดประเภทที่เหมาะสมกับตัวเลขที่คุณต้องการแสดง สิ่งนี้เป็นไปได้เช่น Mathematica สามารถทำได้ แต่มันซับซ้อนและเสียเวลามากและมักไม่คุ้มกับความพยายามเพราะคุณไม่ต้องการความแม่นยำที่สมบูรณ์แบบ แต่คุณต้องการความแม่นยำที่ดีและนั่นคือสิ่งที่โดยทั่วไปแล้วการลอยตัวจะทำได้ดีกว่าจำนวนเต็ม
leftaroundabout

53

คุณสามารถใช้พวกเขาเมื่อคุณกำลังอธิบายอย่างต่อเนื่องมูลค่ามากกว่าที่ไม่ต่อเนื่องหนึ่ง มันไม่ซับซ้อนที่จะอธิบายมากกว่านั้น เพียงอย่าทำผิดที่สมมติว่าค่าใด ๆ ที่มีจุดทศนิยมนั้นต่อเนื่อง หากมีการเปลี่ยนแปลงทั้งหมดในครั้งเดียวเช่นเพิ่มเงินมันไม่ต่อเนื่อง


28

คุณมีสองคำถามที่นี่จริงๆ

ทำไมทุกคนต้องใช้คณิตศาสตร์เลขทศนิยม

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

ฉันเคยใช้เลขทศนิยมในหลาย ๆ พื้นที่ในอาชีพการเขียนโปรแกรมของฉัน: เคมี, ทำงานกับ AutoCAD และแม้แต่การเขียนโปรแกรมจำลอง Monte Carlo เพื่อคาดการณ์ทางการเงิน ในความเป็นจริงมีผู้ชายคนหนึ่งชื่อเดวิดอีชอว์ที่ใช้เทคนิคการสร้างแบบจำลองทางวิทยาศาสตร์แบบอิงจุดลอยตัวกับวอลล์สตรีทเพื่อสร้างเงินนับพันล้าน

และแน่นอนว่ามีคอมพิวเตอร์กราฟิก ฉันปรึกษาเกี่ยวกับการพัฒนา eye candy สำหรับส่วนต่อประสานผู้ใช้และพยายามทำเช่นนั้นทุกวันนี้โดยที่ไม่เข้าใจจุดลอยตัวตรีโกณมิติแคลคูลัสและพีชคณิตเชิงเส้นคงเป็นเหมือนการแสดงการต่อสู้ด้วยปืนพกด้วยปืนพก

ทำไมทุกคนจะต้องลอยเมื่อเทียบกับคู่ ?

ด้วยมาตรฐาน IEEE 754 แสดงมาตรฐาน 32 บิตลอยช่วยให้คุณมีประมาณ 7 ตัวเลขทศนิยมของความถูกต้องและเลขยกกำลังอยู่ในช่วง 10 -38ถึง 10 38 64 บิตคู่จะช่วยให้คุณประมาณ 15 ตัวเลขทศนิยมของความถูกต้องและเลขยกกำลังอยู่ในช่วง 10 -307ถึง 10 307

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

แต่อย่างละเอียดยิ่งขึ้นมีปัญหาที่เรียกว่า "ข้อผิดพลาด roundoff" เรียกขาน การแทนจุดลอยตัวแบบไบนารีจะใช้ได้กับค่าที่ชิ้นส่วนที่เป็นเศษส่วนมีตัวหารคือกำลัง 2 เช่น 1/2, 1/4, 3/4 เป็นต้นหากต้องการเป็นตัวแทนเศษส่วนอื่น ๆ เช่น 1/10 คุณจะ "ปัดเศษ" ค่าเป็นเศษส่วนไบนารีใกล้เคียงที่สุด แต่มันผิดเล็กน้อย - นั่นคือ "ข้อผิดพลาด roundoff" จากนั้นเมื่อคุณคำนวณทางคณิตศาสตร์กับตัวเลขที่ไม่ถูกต้องความไม่ถูกต้องของผลลัพธ์อาจเลวร้ายยิ่งกว่าที่คุณเริ่มต้นด้วย - บางครั้งเปอร์เซ็นต์ความผิดพลาดจะทวีคูณหรือทวีคูณทวีคูณ

อย่างไรก็ตามยิ่งเลขฐานสองที่คุณต้องทำงานมากเท่าไหร่การแสดงเลขฐานสองแบบปัดเศษของคุณจะยิ่งใกล้เคียงกับจำนวนที่คุณพยายามแสดงดังนั้นข้อผิดพลาดของการปัดเศษจะมีขนาดเล็กลง จากนั้นเมื่อคุณทำคณิตศาสตร์กับมันถ้าคุณมีตัวเลขจำนวนมากที่จะทำงานกับคุณสามารถดำเนินการได้มากขึ้นก่อนที่ข้อผิดพลาดในการปัดเศษสะสมจะเกิดปัญหาขึ้น

ที่จริงแล้ว 64 บิตเป็นสองเท่าพร้อมด้วยทศนิยม 15 หลักของพวกเขานั้นไม่ดีพอสำหรับแอปพลิเคชั่นมากมาย ฉันใช้ตัวเลขจุดลอยตัว 80 บิตในปี 1985 และตอนนี้ IEEE กำหนดประเภทจุดลอยตัว 128 บิต (16 ไบต์) ซึ่งฉันสามารถจินตนาการได้ว่าใช้


2
+1 ประสบการณ์ของฉันกับระบบควบคุมความละเอียดสูงเช่นกล้องโทรทรรศน์สำหรับดาราศาสตร์ก็คือ 64 บิตเป็นสองเท่าไม่ดีพอถ้าคุณไม่เรียงลำดับคำของคุณ เหมือนกันสำหรับการควบคุมอัคคีภัยและการนำทางระยะไกล
Tim Williscroft

20

มันเป็นความเข้าใจผิดทั่วไปว่าทุกที่ที่คุณจัดการกับเงินคุณควรเก็บค่าไว้เป็นจำนวนเต็ม (เซนต์) ในบางกรณีอย่างเช่นร้านค้าออนไลน์มันเป็นเรื่องจริงถ้าคุณมีสิ่งที่ก้าวหน้ากว่านั้นก็ไม่ได้ช่วยอะไรมาก

ลองดูตัวอย่าง: นักพัฒนาทำเงินได้ $ 100,000 ต่อปี เงินเดือนที่แน่นอนของเขาคืออะไร? การใช้จำนวนเต็มคุณจะได้รับผลลัพธ์ $ 8333.33 (¢ 833333) ซึ่งคูณด้วย 12 คือ $ 99,999.96 การทำให้มันเป็นจำนวนเต็มช่วยได้ไหม? ไม่มันไม่ได้

ธนาคารใช้ค่าทศนิยม / จำนวนเต็มเสมอหรือไม่ พวกเขาทำเพื่อส่วนธุรกรรม แต่ตัวอย่างเช่นทันทีที่คุณเริ่มพูดคุยกับวาณิชธนกิจยกเว้นการติดตามธุรกรรมจริงทุกอย่างก็จะลอย เนื่องจากเป็นโค้ดภายในองค์กรคุณจะไม่เห็นมัน แต่คุณสามารถใช้จุดสูงสุดที่QuantLibซึ่งเป็นหลักเดียวกัน (ยกเว้นที่สะอาดยิ่งขึ้น ;-)

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


1
@ Job - ตำแหน่งทศนิยมและทศนิยมนั้นแตกต่างกันมาก คุณสามารถเก็บ 0.1 ได้อย่างแม่นยำในรูปแบบทศนิยม แต่ไม่สามารถอยู่ในทศนิยมหรือสอง
Scott Whitlock

3
ฉันมีคำถามอื่น ถ้าคุณจ่าย$100,000/12และใช้ทุ่น ทำไมผลลัพธ์ถึงเป็น $ 100,000 อย่างแน่นอน ทำไมจะไม่มีทุ่น (หรือทศนิยม) ปัดขึ้นหรือลงทุกครั้งที่มีคนจ่าย? ฉันกำลังพูดถึงเมื่อเขียนเช็ค (คุณไม่สามารถทำ 1/2 หรือ 1/3 เซ็นต์) หรือเงินฝากโดยตรง (ฉันคิดว่ามันมีข้อ จำกัด เดียวกัน)

@acid >>> x = 100000 / 12.0 x >>> * 12 100,000.0
vartec

อ่านความคิดเห็นของฉันอีกครั้ง? คำถามของฉันคือเมื่อฉันใช้ซอฟต์แวร์เพื่อสร้างการตรวจสอบทุกเดือน เนื่องจากเราไม่สามารถจ่าย 1/2 เซนต์ได้อย่างไรคน ๆ นั้นจะได้รับเงินเต็มจำนวนหลังจากหนึ่งปีได้อย่างไร

2
@ กรด: คุณไม่สามารถใช้การหารแบบตรงไม่ว่าคุณจะใช้จำนวนเต็มทศนิยมหรือหารเป็นทศนิยมแล้วก็ปัด นั่นคือประเด็นทั้งหมดการใช้ทศนิยมไม่ได้ช่วยในกรณีนี้
vartec

4

สิ่งที่คุณอธิบายไว้นั้นเป็นสิ่งที่ดีอย่างสมบูรณ์ในการแก้ไขสถานการณ์ที่คุณควบคุมอินพุตและเอาต์พุตทั้งหมด

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

ในความเป็นจริงคุณจะพบปัญหาเหล่านี้แม้ว่าคุณจะใช้รายการที่คุณ เมื่อคำนวณภาษี 17.5% จากราคาหนึ่งคุณจะได้รับเซนต์เศษส่วนไม่ว่าคุณจะเก็บค่าเป็นดอลลาร์หรือเซนต์ คุณต้องปัดเศษให้ถูกต้องเนื่องจากผู้เสียภาษีรู้สึกเสียใจมากหากคุณไม่จ่ายเงินให้เขามากพอ การใช้moneyประเภทที่ถูกต้อง(สิ่งที่พวกเขาอยู่ในภาษาที่คุณใช้) จะช่วยให้คุณรอดพ้นจากความเจ็บปวด


ประเภทเงินคืออะไร? (ลิงก์ภาษาหรือการอ้างอิง) และทำไมประเภท 'ถูกต้อง' คืออะไร เป็นเพราะ ... 128bits หรือมากกว่านั้น? ทำไมคนอื่นถึงใช้ 'อุบาย' ของฉันไม่ถูกต้อง คุณมีจำนวนเต็มร้อยละ หากคุณคูณด้วย 0.175 คุณจะได้รับจำนวนเต็มและใช้สำหรับสิ่งที่คุณต้องการ คิดเกี่ยวกับตัวอย่างของคุณฉันคิดว่าลอยจะสามารถเก็บค่าของฉันด้วยความแม่นยำเพียงพอ แต่ฉันไม่ต้องกังวลเกี่ยวกับ 0.3f == 0.3d เป็นเท็จ -edit- และ +1

1
@ acidzombie24 - ฉันไม่ได้หมายถึงประเภทเฉพาะ แต่สิ่งที่เคยพิมพ์ภาษาของคุณใช้เพื่อเป็นตัวแทนของค่าเงิน ถ้าคุณมี 10 เซ็นต์และคูณด้วย 0.175 คุณก็จะมี 1.75 เซนต์คุณจะจัดการกับเลขคณิตจำนวนเต็มได้อย่างไร? 1 เซ็นต์หรือ 2 เซ็นต์หรือไม่ ได้รับมันผิดและลูกค้าของคุณจะจบลงด้วยการเป็นเจ้าของคนเสียภาษีจำนวนมากของเงิน
ChrisF

คุณไม่ควรคูณ 10 (จำนวนเต็ม) ด้วย. 175 (จำนวนจริง / ลอยตัว) เพราะคุณไม่ควรผสมตัวเลขที่แน่นอนกับตัวเลขที่ไม่แน่นอน ผลลัพธ์จะไม่แน่นอน กล่าวอีกนัยหนึ่งในระบบของจำนวนที่แน่นอนค่าเช่น. 175 จะไม่มีอยู่จริงและนี่คือการคำนวณที่ไม่มีความรู้สึก ทางออกที่ดีกว่าคือการคูณ 10,000 ถึง 175 และใส่จุดทศนิยมด้วยตนเองตามความเหมาะสม
Barry Brown

8
@ Barry - ฉันรู้ ฉันพยายามแสดงให้เห็นถึงประเภทของปัญหาที่คุณได้รับ นอกจากนี้ยังมีค่าเช่น 0.175 หากอัตราภาษีเป็น 17.5% และคุณจำเป็นต้องคำนวณภาษีสำหรับรายการที่มีค่าใช้จ่าย 10 เซ็นต์
ChrisF

1
@acidzombie: ประเภทที่ถูกต้องเพื่อใช้กับเงินเป็นทศนิยมถาวรที่มีความแม่นยำสูง (อย่างน้อย 4 จุดทศนิยม) ไม่ใช่แค่ ifs, ands หรือ buts การเก็บค่าเงินเป็นเซนต์ไม่เพียงพอเพราะในทางปฏิบัติมันให้ความแม่นยำสองจุดเท่านั้น
Aaronaught

3

"พระเจ้าสร้างจำนวนทั้งหมดทุกอย่างเป็นงานของมนุษย์" - Leopold Kronecker (1886)

ตามคำนิยามคุณไม่จำเป็นต้องมีตัวเลขชนิดอื่น ความสมบูรณ์ของภาษาทัวริงนั้นขึ้นอยู่กับความสัมพันธ์แบบง่าย ๆ ระหว่างตัวเลขหลายชนิด หากคุณสามารถทำงานกับตัวเลขทั้งหมด (a / k / ตัวเลขธรรมชาติ) คุณสามารถทำอะไรก็ได้

คำถามนั้นค่อนข้างกว้างขวางเพราะคุณไม่ต้องการมัน บางทีคุณอาจต้องการสถานที่ที่สะดวกหรือดีที่สุดหรือราคาถูกกว่าหรือบางสิ่ง?


7
นอกจากนี้เรายังสามารถแจกจ่ายด้วยจำนวนเต็มเนื่องจากเราสามารถสร้างมันได้โดยใช้การดำเนินการตามทฤษฎีเซตและเซตว่างเท่านั้น แต่สิ่งนั้นและการโต้แย้งจากความสมบูรณ์ของทัวริงคือการลดเชิงวิชาการที่นำไปสู่สุดขั้ว
Bob Murphy

4
นอกจากนี้ทัวริงสมบูรณ์ใช้กับคอมพิวเตอร์เท่านั้น ตัวเลขทั้งหมดหรือแม้กระทั่ง rationals จะเสร็จสมบูรณ์ทางคณิตศาสตร์เนื่องจากไม่ได้ปิดการบรรจบกันของลำดับ Cauchy ดังนั้น Kronecker จึงเต็มไปด้วยอากาศร้อน: หากคุณต้องการพื้นที่ตัวชี้วัดที่สมบูรณ์ซึ่งรวมถึงตัวเลขทั้งหมดคุณจะต้องได้รับจริง: xkcd.com/849
Bob Murphy

1
@ บ๊อบเมอร์ฟี่: "การลดทอนวิชาการถือเป็นสุดยอด" แม่นยำ. คำถามไม่ดีและนำไปสู่การตอบนี้เป็นไปได้
S.Lott

2

ในประโยคทศนิยมชนิดทศนิยมจะสรุปการแปลงเป็นและจากค่าจำนวนเต็ม (ซึ่งคอมพิวเตอร์ทุกเครื่องรู้วิธีจัดการกับระดับไบนารีนั้นไม่มีทศนิยมในฐานสอง) ที่ให้ตรรกะโดยทั่วไปง่ายต่อการ เข้าใจอินเตอร์เฟสสำหรับการคำนวณตัวเลขทศนิยม

ตรงไปตรงมาโดยบอกว่าคุณไม่จำเป็นต้องลอยตัวเพราะคุณรู้วิธีการทำเลขทศนิยมโดยใช้จำนวนเต็มเหมือนกับบอกว่าคุณรู้วิธีการคำนวณทางคณิตศาสตร์แบบยาวดังนั้นทำไมต้องใช้เครื่องคิดเลข ดังนั้นคุณจึงรู้แนวคิด; ไชโย ไม่ได้หมายความว่าคุณต้องใช้ความรู้นั้นตลอดเวลา บ่อยครั้งที่เร็วกว่าถูกกว่าและเข้าใจได้ง่ายกว่าไม่ใช่ไบนารี - เสียงหวือเพียงแค่พูดว่า 3.5 + 4.6 = 8.1 แทนที่จะแปลงมะเดื่อซิกเป็นจำนวนเต็ม


1

ข้อได้เปรียบหลักของประเภทจุดลอยตัวคือจากมุมมองแบบรันไทม์สองหรือสามรูปแบบ (ฉันหวังว่าภาษาอื่น ๆ ที่รองรับรูปแบบ 80 บิต) จะเพียงพอสำหรับการคำนวณส่วนใหญ่ที่รวดเร็ว หากภาษาการเขียนโปรแกรมสามารถรองรับตระกูลประเภทจุดคงที่ได้อย่างง่ายดายความซับซ้อนของฮาร์ดแวร์ที่จำเป็นสำหรับระดับประสิทธิภาพที่กำหนดมักจะต่ำกว่าด้วยประเภทจุดคงที่มากกว่าแบบจุดลอยตัว น่าเสียดายที่การให้การสนับสนุนดังกล่าวอยู่ไกลจาก "ง่าย"

สำหรับภาษาการเขียนโปรแกรมเพื่อตอบสนอง 98% ของความต้องการเชิงตัวเลขของแอปพลิเคชั่นอย่างมีประสิทธิภาพนั้นจะต้องมีหลายสิบประเภท ยิ่งไปกว่านั้นแม้ว่าภาษาการเขียนโปรแกรมมีการสนับสนุนจุดคงที่ที่ยอดเยี่ยมบางแอปพลิเคชันยังคงต้องรักษาความแม่นยำสัมพัทธ์คงที่ในช่วงที่มีขนาดใหญ่พอที่จะต้องใช้ทศนิยม เนื่องจากคณิตศาสตร์จุดลอยตัวมีความจำเป็นในบางโอกาสในกรณีใด ๆ การมีผู้จำหน่ายฮาร์ดแวร์ให้ความสำคัญกับประสิทธิภาพทางคณิตศาสตร์ด้วยรูปแบบจุดลอยตัวสองหรือสามรูปแบบและการใช้รหัสใช้รูปแบบเหล่านั้นเมื่อใดก็ตามที่ทำงานได้ดีพอสมควร "ปังสำหรับเจ้าชู้" มากกว่าที่จะพยายามปรับพฤติกรรมของคณิตศาสตร์จุดคงที่ให้เหมาะสมที่สุด

คณิตศาสตร์จุดคงที่มีข้อได้เปรียบมากกว่ากับตัวประมวลผล 8 บิตและ 16 บิตมากกว่าตัวประมวลผลแบบ 32 บิต บนตัวประมวลผล 8 บิตในสถานการณ์ที่ 32 บิตไม่พอเพียงชนิด 40 บิตจะเสียค่าใช้จ่ายพื้นที่มากขึ้น 25% และใช้เวลามากกว่า 25-50% มากกว่าประเภท 32 บิตและต้องใช้ 37.5% ใช้พื้นที่น้อยกว่าและใช้เวลาน้อยกว่า 37.5-60% สำหรับประเภท 64 บิต บนแพลตฟอร์ม 32 บิตหากประเภท 32 บิตไม่เพียงพอสำหรับบางสิ่งบางอย่างมักจะมีเหตุผลเล็กน้อยที่จะใช้อะไรน้อยกว่า 64 บิต หากประเภทจุดคงที่ 48 บิตจะเพียงพอส่วน "64 บิต" สองเท่าจะทำงานได้เช่นเดียวกับประเภทจุดคงที่


0

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

double average(List<Double> data) {
  double ans = 0;
  for(Double d : data) {
    ans += d;
  }
  return ans / data.size();
}

เหตุผลก็คือสำหรับรายการที่มีขนาดใหญ่พอคุณจะสูญเสียจุดข้อมูลทั้งหมดเมื่อansมีขนาดใหญ่พอ (ดูตัวอย่างเช่นนี้ ) ปัญหาของรหัสนี้คือสำหรับรายการเล็ก ๆ มันอาจเป็นไปได้ที่จะทำงานได้

โดยส่วนตัวแล้วฉันคิดว่าคุณควรใช้เมื่อ: ก) การคำนวณต้องรวดเร็ว b) คุณไม่สนใจว่าผลลัพธ์จะเป็นไปได้ (เว้นแต่คุณจะรู้ว่าคุณกำลังทำอะไรอยู่)


-1

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

สถาปัตยกรรมของวันนี้ (คร่าวๆ) มีช่วงจำนวนเต็มที่ลงนามเป็น +/- 2,147,483,647 (32 บิต) หรือ +/- 9,223,372,036,854,775,807 (64 บิต) ไม่ได้ลงนามขยายว่าโดยปัจจัย 2

IEEE 754 ลอยตัว (ประมาณ) เริ่มจาก +/- 1.4 × 10 ^ −45 ถึง 3.4 × 10 ^ 38 ดับเบิลขยายช่วงนั้นเป็น +/- 5 × 10−324 ± 2.225 × 10 ^ −308 โดยมีเงื่อนไขและข้อมูลเฉพาะมากมายที่นี่

แน่นอนเหตุผลที่ชัดเจนที่สุดคือคุณอาจต้องใช้ -0 ;-)


ตัวเลขส่วนใหญ่มาจากบทความวิกิพีเดียและมีความหมายเพื่อเป็นตัวอย่าง ยกเว้น -0 นั่นเป็นเรื่องสนุก
สตีเฟ่น

ปัญหาคือมีจำนวนเต็มจำนวนมากในช่วงใหญ่ที่ไม่ได้แสดงเลย
Barry Brown

@BarryBrown ถูกต้องแน่นอน "เงื่อนไขและข้อมูลเฉพาะจำนวนมากถูกละเว้น" แม้ว่า
Stephen

-1

เหตุผลปกติคือเนื่องจากรวดเร็วเนื่องจาก JVM มักใช้การสนับสนุนฮาร์ดแวร์พื้นฐาน (เว้นแต่คุณจะใช้เข้มงวด)

ดูhttps://stackoverflow.com/questions/517915/when-to-use-strictfp-keyword-in-javaสำหรับความหมายที่เข้มงวด


คณิตศาสตร์เลขทศนิยมจะเร็วกว่าเลขจำนวนเต็มหรือไม่ การคำนวณจุดลอยตัวของตัวประมวลผลใดที่ใช้รอบน้อยกว่าการคำนวณจำนวนเต็ม
this.josh

1
@ this.josh ขึ้นอยู่กับจำนวนตัวเลขที่คุณมีในตัวเลข จำนวนเต็มไม่สามารถหารได้อย่างแม่นยำซึ่งอาจหรืออาจไม่สำคัญ

-2

นั่นเป็นเหตุผลที่เราต้องการระบบปฏิบัติการ 256 บิต

ความยาวของไม้กระดาน (ระยะทางที่เล็กที่สุดที่คุณสามารถวัดได้) = 10 ^ -35m
จักรวาลที่สังเกตได้คือ 14Bn parsecs ข้าม = 10 ^ 25m
ดังนั้นคุณสามารถวัดทุกอย่างในหน่วยของความยาวไม้กระดานเป็นจำนวนเต็มถ้าคุณมีความแม่นยำเพียง 200 บิต


2
-1: ถ้าคุณจำลองสิ่งต่าง ๆ ในระดับที่ใหญ่กว่าเอกภพที่สังเกตได้
amara

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