2012-01-16 9 views
5

(değil gerçek kodu):C# ve C++ 'da 2'ye bölünmek yerine, bir float/double'ı 0,5 ile çarpmak güvenli midir? Bu gibi şeyler için Temelde

for(int i = 0; i < 1000000000; ++i) 
{ 
    Vert v0 = mesh.polygons[i].edges[0].vert0; 
    Vert v1 = mesh.polygons[i].edges[0].vert1; 

    Vector3 center = (v0.pos + v1.pos)/2; 
} 

v0.pos tip Vector3<float, float, float> ait olmakla Vector3<double, double, double> olabilir.

güvenli Bu erken optimizasyon gibi görünebilir ancak bu kadar hızlı noktaları (nokta bulutları) milyarlarca çağrıda olacağını mümkün olduğunca olmak zorunda sadece ?:

Vector3 center = (v0.pos + v1.pos) * 0.5; 

yapmak mı.

+6

Her iki seçeneğin performansını ölçtüğünüzde ne olur? Optimizasyon hakkında bu platformda, hedef platformunuzda * ölçüm yapmadan * bahsedemezsiniz. –

+0

Her iki şekilde de ölçün. Ama derleyiciniz '2'ye bölünmek için zaten bit-kaydırmaya geri dönmelidir. – CaffGeek

+1

Greg ile anlaştılar. Ayrıca, hızdan önce doğruluğa odaklanmanız gerektiğini unutmayın.Çoğu zaman, derleyici bunu sizin için en iyi şekilde kullanır (özellikle editörleri kullandığınızda). – TheBuzzSaw

cevap

3

değil C++ herhangi bir yöntemle uzman, ancak C# 'de, bu durumu:

var a = new Func<float, float, double>((float f1, float f2) => (f1 + f2) * 0.5); 
var b = new Func<float, float, double>((float f1, float f2) => (f1 + f2)/2); 

önceki bu IL oluşturur:

  1. Yükler argümanlar
  2. ekler (üreten tek)
  3. İkili bir sonucu dönüştürür
  4. Çift bağımsız değişkeni yükler (0,5)
  5. çarpar
  6. (sabit bir tam sayı
  7. Yükler (tek üreten) bir sonuç

ve ikinci

  1. Yükler
  2. ekler argümanlar döndürür (bir çift üreten) 2)
  3. Bölücüler (tek/tamsayı tek ürettiği için tek bir üretme)
  4. çift
  5. sonucu dönüştürür bir sonuç

Çarpma 2 çift yapılır çünkü eski olasılıkla ikinci mekanizma aşağıdakiler oysa, çift hassasiyet sonuçlanan yüksek hassasiyet sahip olacağı beni vuruyor İade Bölme, bir çifte doğru olan bir tek üzerinde gerçekleştirilir (ancak yine de tek bireyin doğruluğuna sahip olacaktır).

Bu beni taşır:

Console.Out.WriteLine(((double)1) * ((double)1/3)); 
Console.Out.WriteLine((1)/((float)3)); 

üretir: kaybetme hassasekstra hassas kazanıyor eğer

0.333333333333333 
0.3333333 

Yani, 'güvenli', belki tamam.

+0

*' nize erişirken dizi dizini yerine dizgi yerine gerçekten işaretçiler kullanıyor olmanız gerekir." 5. Sonuçları ikiye dönüştürür "*: Bu delegeler Func 'herhangi bir şans? – Groo

+0

Yep, üzgünüm, üzerimde kötü bir kopya ... Sabit. –

+0

Yeterince doğru ve iyi bir nokta, ama bana göre bir çarpmanın bölünmeyi değiştirmenin sonucu değiştirip değiştiremeyeceği sorusu var (her ikisi için de aynı girişi varsayarak), bu durumda bunun nasıl olacağını anlamıyorum. vaka. yani, bölme (f1 + f2), bölmeden önce ikiye katlamak ya da 0,570'e katarak, sonuç aynı – Voo

İlgili konular