ระดับ“ ญาติ” ที่ใหญ่ที่สุดที่ฉันสามารถใช้ในการลอยคืออะไร


13

เช่นเดียวกับที่แสดงให้เห็นด้วยเกมอย่าง dungeon siege และ KSP ระดับที่มากพอที่จะเริ่มมีข้อบกพร่องเนื่องจากวิธีการทำงานของ floating point คุณไม่สามารถเพิ่ม 1e-20 ถึง 1e20 โดยไม่สูญเสียความแม่นยำ

หากฉันเลือกที่จะ จำกัด ขนาดของระดับฉันจะคำนวณความเร็วต่ำสุดที่วัตถุของฉันสามารถเคลื่อนที่ได้จนกว่าจะเริ่มขาด ๆ หาย ๆ ได้อย่างไร

คำตอบ:


26

32 บิตลอยมี mantissa

นั่นหมายถึงแต่ละหมายเลขแสดงเป็น 1.xxx xxx xxx xxx xxx xxxxx คูณกำลังบางส่วนของ 2 โดยแต่ละ x เป็นเลขฐานสองทั้ง 0 หรือ 1 (ยกเว้นตัวเลขที่มีขนาดเล็กมากน้อยกว่า - พวกเขาเริ่มต้นด้วย 0 แทน 1 แต่ฉันจะไม่สนใจสิ่งต่อไปนี้)2126

ดังนั้นในช่วงจากและคุณสามารถแสดงตัวเลขใด ๆ ภายในความแม่นยำของ2i2(i+1)±2(i24)

เป็นตัวอย่างสำหรับ , จำนวนที่น้อยที่สุดในช่วงนี้คือ1 จำนวนที่น้อยที่สุดต่อไปคือ23}) หากคุณต้องการที่จะเป็นตัวแทนของคุณจะมีการปัดเศษขึ้นหรือลงสำหรับข้อผิดพลาดของทางใดทางหนึ่งi=0(20)1=1(20)(1+223)1+224224

In this range:                You get accuracy within:
-----------------------------------------------
         0.25   -     0.5    2^-26 = 1.490 116 119 384 77 E-08
         0.5    -     1      2^-25 = 2.980 232 238 769 53 E-08
         1     -      2      2^-24 = 5.960 464 477 539 06 E-08
         2     -      4      2^-23 = 1.192 092 895 507 81 E-07
         4     -      8      2^-22 = 2.384 185 791 015 62 E-07
         8     -     16      2^-21 = 4.768 371 582 031 25 E-07
        16     -     32      2^-20 = 9.536 743 164 062 5  E-07
        32     -     64      2^-19 = 1.907 348 632 812 5  E-06
        64     -    128      2^-18 = 0.000 003 814 697 265 625
       128    -     256      2^-17 = 0.000 007 629 394 531 25
       256    -     512      2^-16 = 0.000 015 258 789 062 5
       512    -   1 024      2^-15 = 0.000 030 517 578 125
     1 024    -   2 048      2^-14 = 0.000 061 035 156 25
     2 048    -   4 096      2^-13 = 0.000 122 070 312 5
     4 096    -   8 192      2^-12 = 0.000 244 140 625
     8 192   -   16 384      2^-11 = 0.000 488 281 25
    16 384   -   32 768      2^-10 = 0.000 976 562 5
    32 768   -   65 536      2^-9  = 0.001 953 125
    65 536   -  131 072      2^-8  = 0.003 906 25
   131 072   -  262 144      2^-7  = 0.007 812 5
   262 144   -  524 288      2^-6  = 0.015 625
   524 288 -  1 048 576      2^-5  = 0.031 25
 1 048 576 -  2 097 152      2^-4  = 0.062 5
 2 097 152 -  4 194 304      2^-3  = 0.125
 4 194 304 -  8 388 608      2^-2  = 0.25
 8 388 608 - 16 777 216      2^-1  = 0.5
16 777 216 - 33 554 432      2^0   = 1

ดังนั้นหากหน่วยของคุณเป็นเมตรคุณจะเสียความแม่นยำมิลลิเมตรประมาณ 16 484 - 32 768 แบนด์ (ประมาณ 16-33 กม. จากจุดกำเนิด)

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

  • ถ้าเราใช้หน่วยเซนติเมตรเป็นหน่วยของเราเราจะสูญเสียความแม่นยำมิลลิเมตรที่ 1 048 576-2 097 152 แบนด์ (10-21 กม. จากแหล่งกำเนิด)

  • ถ้าเราใช้เฮกตาร์เป็นหน่วยของเราเราจะสูญเสียความแม่นยำมิลลิเมตรที่ 128-256 แบนด์ (13-26 กม. จากแหล่งกำเนิด)

... ดังนั้นการเปลี่ยนหน่วยคำสั่งขนาดสี่ยังคงจบลงด้วยการสูญเสียความแม่นยำมิลลิเมตรที่ใดที่หนึ่งในช่วงสิบกิโลเมตร ทุกอย่างที่เราเปลี่ยนคือตำแหน่งที่ตรงกับวงนั้น (เนื่องจากความไม่ตรงกันระหว่างเลขฐาน 10 และเลขฐาน 2) ไม่ได้ขยายพื้นที่ของเราอย่างมาก

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

หากคุณทราบระดับความแม่นยำที่คุณต้องการ (กล่าวคือมีช่วงของแผนที่ 0.01 หน่วยถึงประมาณ 1 px ที่ระยะการรับชม / ปฏิสัมพันธ์ปกติของคุณและออฟเซตที่เล็กกว่ามองไม่เห็น) คุณสามารถใช้ตารางด้านบนเพื่อค้นหาตำแหน่งที่คุณสูญเสีย ความแม่นยำและถอยหลังคำสั่งขนาดเล็กเพื่อความปลอดภัยในกรณีที่การดำเนินการสูญเสีย

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


1
การกลับมาเป็นอีกหนทางหนึ่งที่แน่นอน!
Floris

2
แล้วการใช้พิกัดจุดคงที่ล่ะ? อาจจะมีจำนวนเต็ม 64 บิตถ้าจำเป็น?
API-Beast

คำถามคือภูมิภาคที่มีศูนย์กลางที่สามารถอยู่ใหม่ได้มีขนาดใหญ่เพียงใด ถ้าเป็นตัวอย่างในเกมที่ฉันต้องการถ่ายภาพในระยะไกลด้วยการซูมที่แรงฉันต้องใช้สองเท่าหรือลอยพอหรือไม่? มันจะดีกว่าหรือไม่ที่จะแนะนำซ้ำตามทรีทรีหรืออัลกอริทึมไทล์
jokoon

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

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

3

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

หากคุณต้องการโลกขนาดใหญ่และฟิสิกส์ที่สอดคล้องกันจะดีกว่าถ้าใช้คลาสคะแนนคงที่

ตัวอย่างเช่นการยิงลูกกระสุนปืนจากที่ใดก็ได้ในโลกจะให้ผลลัพธ์เดียวกันและ 64 บิตที่กำหนด (32.32) ให้ความแม่นยำและความแม่นยำมากกว่าเกมอื่น ๆ หากหน่วยของคุณคือ 1 เมตรคุณยังคงอยู่ที่ 232 picometers ความแม่นยำ 2147483km ห่างจากจุดกำเนิด

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

ในฐานะที่เป็นโบนัสในวงกว้างและ AABB มีแนวโน้มที่จะเร็วขึ้นในจุดคงที่เนื่องจากความล่าช้าในการ FPU นอกจากนี้ยังเร็วกว่าในการแปลงจุดคงที่ไปเป็นดัชนี octree (หรือ quadtree) ในขณะที่คุณสามารถทำการหลอกลวงได้ง่าย

การดำเนินการเหล่านั้นไม่ได้รับประโยชน์มากนักจากคำสั่ง SIMD และการวางท่อซึ่งปกติจะซ่อน FPU latency

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


-3

คุณสามารถหลีกเลี่ยงได้ทั้งหมดโดยการคูณ
แทนที่จะทำงานกับโฟลทแค่คูณพวกมันด้วย 10 ^ (x) เก็บพวกมันและเมื่อต้องการคูณอีกครั้งด้วย 10 ^ (- x)
จากนั้นขึ้นอยู่กับประเภทของ int ที่คุณต้องการใช้


2
นี่ไม่ได้เป็นการหลีกเลี่ยงปัญหา รูปแบบจุดคงที่ยังคงมีความแม่นยำและขอบเขต จำกัด ยิ่งช่วงยิ่งมีความแม่นยำน้อยลง (ขึ้นอยู่กับตำแหน่งที่คุณใส่จุดทศนิยมคงที่) - ดังนั้นการตัดสินใจว่า "ฉันจะสร้างระดับได้ขนาดไหนโดยไม่มีข้อผิดพลาดในการปัดเศษ ยังคงใช้
DMGregory

3
ยิ่งไปกว่านั้น base-10 ยังใช้งานไม่ได้ ตัวเลขจุดคงที่ทำงานได้ดีขึ้นมากเมื่อคุณแบ่งจำนวนเต็มในรูปแบบของบิต (พิจารณา 26.6 ที่ไม่ได้ลงนาม - ส่วนประกอบที่เป็นเศษส่วนจะต่ำกว่า 6 บิต ( 1.0 / 64.0 * x & 63) และส่วนประกอบที่เป็นเพียง x >> 6 . มันง่ายกว่าที่จะนำไปใช้มากกว่าการเพิ่มบางสิ่งให้เป็นพลังสิบ
Andon M. Coleman
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.