Şamandıra kullanarak yapabileceğim en büyük “göreceli” seviye nedir?


13

Tıpkı zindan kuşatması ve KSP gibi oyunlarda gösterildiği gibi, kayan noktanın nasıl çalıştığı nedeniyle hatalara sahip olmaya yetecek kadar büyük bir seviye. Doğruluğu kaybetmeden 1e-20'ye 1e20 ekleyemezsiniz.

Seviyemin boyutunu sınırlamayı seçersem, nesnemin dalgalı olmaya başlayana kadar hareket edebileceği minimum hızı nasıl hesaplayabilirim?

Yanıtlar:


26

32 bit şamandırada 23 bit mantis vardır .

Bu, her sayının 1.xxx xxx xxx xxx xxx xxx xxx xx çarpı 2 olarak temsil edildiği anlamına gelir; burada her x, 0 veya 1 ikili sayıdır. ( den küçük çok küçük denormalize sayılar hariç, - 1 yerine 0 ile başlıyorlar, ancak aşağıdakiler için onları görmezden geleceğim)2-126

Yani ve aralığında , doğruluktaki herhangi bir sayıyı temsil edebilirsiniz2ben2(ben+1)±2(ben-24)

Örnek olarak, , bu aralıktaki en küçük sayı . Bir sonraki en küçük sayı . ı temsil etmek istiyorsanız, her iki şekilde de hata için yukarı veya aşağı yuvarlamanız gerekir .ben=0(20)1=1(20)(1+2-23)1+2-242-24

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

Üniteleriniz metre ise, 16 484 - 32 768 bandının çevresinde milimetre hassasiyetini kaybedersiniz (başlangıç ​​noktasından yaklaşık 16-33 km).

Genellikle farklı bir ana birim kullanarak bu sorunu çözebileceğinize inanılıyor, ancak bu gerçekten doğru değil, çünkü önemli olan göreceli hassasiyet.

  • Ünitemiz olarak santimetre kullanırsak, 1 048 576-2 097 152 bandında (başlangıç ​​noktasından 10-21 km) milimetre hassasiyetini kaybederiz

  • Ünitemiz olarak hektarmetreler kullanırsak, 128-256 bandında milimetre hassasiyetini kaybederiz (başlangıç ​​noktasından 13-26 km)

... böylece üniteyi dört büyüklük sırasına göre değiştirmek hala onlarca kilometre aralığında bir yerde milimetre hassasiyetinde bir kayıpla sonuçlanıyor. Değiştiğimiz tek şey, tam olarak o bantta (taban-10 ve taban-2 numaralandırma arasındaki uyumsuzluk nedeniyle) oynatılabilir alanımızı önemli ölçüde genişletmediği yerdir.

Oyununuzun ne kadar yanlışlığa tahammül edebileceği, oyununuzun ayrıntılarına, fizik simülasyonuna, varlık boyutuna / çizim mesafelerine, işleme çözünürlüğüne vb.Bağlıdır, böylece kesin bir kesinti ayarlamak zordur. Oluşturma işleminiz orijinden 50 km uzakta olabilir, ancak mermileriniz duvarlardan ışınlanıyor veya hassas bir oyun senaryosu haywire gidiyor. Ya da oyunun iyi oynadığını görebilirsiniz, ancak her şeyin kamera dönüşümündeki yanlışlıklardan zar zor algılanabilir bir titreşimi vardır.

İhtiyacınız olan doğruluk düzeyini biliyorsanız (örneğin, 0,01 birimlik bir aralık, tipik görüntüleme / etkileşim mesafenizde yaklaşık 1 piksele eşlenir ve daha küçük bir ofset görünmezdir), nerede kaybettiğinizi bulmak için yukarıdaki tabloyu kullanabilirsiniz. kayıplı işlemler durumunda güvenlik için birkaç büyüklükte geri çekilir.

Ancak, büyük mesafeler hakkında düşünürseniz , oyuncu hareket ettikçe dünyanıza yeniden girerek tüm bunları ortadan kaldırmak daha iyi olabilir . Kökeni etrafında muhafazakar olarak küçük bir kare veya küp şeklinde bir bölge seçersiniz. Oyuncu bu bölgenin dışına çıktığında, onları ve dünyadaki her şeyi, bu bölgenin genişliğinin yarısı kadar çevirerek, oyuncuyu içeride tutar. Her şey birlikte hareket ettiğinden, oynatıcınız bir değişiklik görmez. Yanlışlıklar hala dünyanın uzak bölgelerinde olabilir, ancak genellikle ayaklarınızın altında olmaktan çok daha az fark edilirler ve oyuncunun yakınında her zaman yüksek hassasiyete sahip olduğunuz garanti edilir.


1
Yeniden girmek kesinlikle yoludur!
Floris

2
Sabit nokta koordinatlarını kullanmaya ne dersiniz? Belki gerekirse 64 bit tamsayılarla?
API-Beast

soru şu, bu yeniden merkezli bölge ne kadar büyük olabilir? örneğin oyunumda güçlü bir zumla yüksek bir mesafeden çekim yapmak istiyorsam, kesinlikle iki kat kullanmam gerekir mi yoksa yeterince yüzer mi? Dörtlü bir ağaca veya bir karo algoritmasına göre yeniden girmek daha iyi değil mi?
jokoon

Oluşturma ve fizik sistemleriniz tarafından kullanılan algoritmaların sayısal kararlılığına bağlı olacaktır - bu nedenle belirli bir kod tabanı / motor için kesin olarak bilmenin tek yolu bir test sahnesini denemektir. Tabloyu maksimum doğruluğu tahmin etmek için kullanabiliriz (örn. Bir nesneden 16 km uzaklıktaki bir kamera en az milimetre boyutunda hatalar görme eğiliminde olacaktır, bu nedenle zumunuz piksellerden daha küçük olanları korumak için yeterince geniş olmalıdır - zum gerekiyorsa oyununuz için daha sıkı olmak için iki katına çıkabilir veya akıllı bir matematik gerekebilir), ancak bu varsayımsal sınırdan çok önce kayıplı operasyonlar zinciri problemlerle karşılaşabilir.
DMGregory

Hala grafiksel bir API için dünyayı yeniden eğitmenin ne anlama geldiğini merak ediyorum. Büyük bir örneklenmiş (veya örneklenmemiş) geometri yığınım varsa, bunu yapmak hala güvenli mi? Sanırım TÜM dönüşümleri çevirmek anlamına geliyor, ama bunu birkaç kez yaparsam, kayan nokta hassasiyeti kaybı riski yok mu?
jokoon

3

İçin ihtiyaçları olduğunu kabul edilebilir asgari hareket hızı nedir: sizin fizik ölçeğine bağlıdır gibi cevap zor değil sıfıra kapalı yuvarlanır?

Büyük bir dünyaya ve tutarlı bir fiziğe ihtiyacınız varsa, sabit puan sınıfı kullanmak daha iyidir.

Örneğin, dünyanın herhangi bir yerinden top atmak size aynı sonucu verir ve 64bit sabit nokta (32.32) size büyük miktarda hassasiyet ve çoğu oyunda algılanabilen her şeyden daha fazlasını verir. Üniteniz 1 metre ise, başlangıç ​​noktasından 2147483km uzakta 232 picometers hassasiyetindesiniz.

Programlama işinden tasarruf etmek ve kullanıma hazır bir fizik motoru kullanmak için yerel fiziği yerel hücre içindeki kayan noktalarda yapabilirsiniz. Yine de tüm pratik amaçlar için makul düzeyde tutarlı olacaktır.

Bir bonus geniş faz ve AABB, FPU gecikmesi nedeniyle sabit noktada daha hızlı olma eğilimindedir. Ayrıca, basit bir bit maskelemesi yapabileceğiniz için sabit bir noktayı bir oktree (veya quadtree) dizinine dönüştürmek daha hızlıdır.

Bu operasyonlar normalde FPU gecikmesini gizleyecek olan SIMD talimatları ve boru hatlarından çok fazla faydalanmamaktadır.

Her şeyi oluşturmak için kameranın konumunu sabit noktadan çıkardıktan sonra, büyük bir dünyada kayan nokta sorunlarından kaçınarak ve hala kayan noktaları kullanarak normal bir oluşturucu kullanarak pozisyonları kayan noktaya dönüştürebilirsiniz.


-3

Çarpma ile tamamen önleyebilirsiniz.
Şamandıralarla çalışmak yerine, bunları 10 ^ (x) ile çarpın, saklayın ve gerektiğinde tekrar 10 ^ (- x) ile çarpın.
Bundan, ne tür int kullanmak istediğinize bağlıdır.


2
Bu sorundan kaçınmaz. Sabit noktalı bir biçimin hala son derece hassas ve aralığı vardır - aralık ne kadar büyük olursa, hassasiyet o kadar düşüktür (sabit ondalık noktasını nereye koyduğunuza bağlı olarak) - böylece "görünür yuvarlama hataları olmadan ne kadar büyük bir seviye yapabilirim" kararı hala geçerlidir.
DMGregory

3
Ayrıca, taban-10 çok pratik değildir. Tamsayı bit cinsinden böldüğünüzde sabit nokta sayıları çok daha iyi çalışır (işaretsiz 26.6'yı düşünün - kesirli bileşen daha düşük 6 bittir ( 1.0 / 64.0 * x & 63) ve ayrılmaz kısım basitçe x >> 6'dır) . Bunu uygulamak, bir şeyi on güce yükseltmekten çok daha kolaydır.
Andon M. Coleman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.