0.0039215689 sabiti neyi temsil eder?


310

Çeşitli grafik başlık dosyalarında bu sürekli açılır pencereyi görmeye devam ediyorum

0.0039215689

Belki renk ile ilgili bir şey var gibi görünüyor?

Google'daki ilk hit :

void RDP_G_SETFOGCOLOR(void)
{
    Gfx.FogColor.R = _SHIFTR(w1, 24, 8) * 0.0039215689f;
    Gfx.FogColor.G = _SHIFTR(w1, 16, 8) * 0.0039215689f;
    Gfx.FogColor.B = _SHIFTR(w1, 8, 8) * 0.0039215689f;
    Gfx.FogColor.A = _SHIFTR(w1, 0, 8) * 0.0039215689f;
}

void RDP_G_SETBLENDCOLOR(void)
{
    Gfx.BlendColor.R = _SHIFTR(w1, 24, 8) * 0.0039215689f;
    Gfx.BlendColor.G = _SHIFTR(w1, 16, 8) * 0.0039215689f;
    Gfx.BlendColor.B = _SHIFTR(w1, 8, 8) * 0.0039215689f;
    Gfx.BlendColor.A = _SHIFTR(w1, 0, 8) * 0.0039215689f;

    if(OpenGL.Ext_FragmentProgram && (System.Options & BRDP_COMBINER)) {
        glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, Gfx.BlendColor.R, Gfx.BlendColor.G, Gfx.BlendColor.B, Gfx.BlendColor.A);
    }
}

//...more like this

Bu sayı neyi temsil ediyor? Neden kimse bunu bir sabit olarak ilan etmiyor?

Google'da bunu açıklayan hiçbir şey bulamadım.


16
Kaynak kodunun bunun yerine yazmasının bir nedeni var mı (1.f/255)?
MM

53
Mmmm ... sihirli sayılardan kaçınmanın bir yolu olsaydı ...
Paul Draper

12
1/255 == 0.00(3921568627450980)- parens tekrar anlamına gelir.
jfs

82
Bir sonraki sihirli numaranızla Wolfram Alpha
AakashM

12
nedeni ne olursa olsun, amacını belgelemeden sihirli bir sayı kullanmak çok soğuktur
Isaac Rabinovitch

Yanıtlar:


378

0.0039215689yaklaşık olarak eşittir 1/255.

Bunun OpenGL olduğunu görmek, performans muhtemelen önemlidir. Bu nedenle, bunun performans nedenleriyle yapıldığını tahmin etmek muhtemelen güvenlidir.

Karşılıklı çarpma, 255'e art arda bölmekten daha hızlıdır.


Kenar notu:

Neden böyle bir mikro optimizasyonun derleyiciye bırakılmadığını merak ediyorsanız, bunun nedeni güvenli olmayan bir kayan nokta optimizasyonu olmasıdır. Diğer bir deyişle:

x / 255  !=  x * (1. / 255)

kayan nokta yuvarlama hataları nedeniyle.

Bu nedenle, modern derleyiciler bu optimizasyonu yapacak kadar akıllı olsa da, açıkça bir derleyici bayrağı aracılığıyla söylemediğiniz sürece bunu yapmasına izin verilmez.

İlgili: GCC neden * a * a * a * a * a'yı (a * a * a) * (a * a * a) 'ya optimize etmiyor?


10
Aslında ilk gördüğümde ne olduğunu bilmiyordum. Ama nasıl kullanıldığını görünce, bunun karşılıklı çarpma optimizasyonu olduğundan şüphelendim. Bu yüzden hesap makinemi kontrol ettim ve yeterince eminim - doğru tahmin ettim.
Mistik

55
Yazıldığını görmeyi beklerdim a = b * (1.0f / 255); derleyiciler hala sürekli katlanır, değil mi?
Ilmari Karonen

9
@IlmariKaronen Evet, hala sabit katlama yapıyorlar. Aslında şablon çözünürlükleri ve benzeri şeyler için gereklidir. Ama onu bir sabit ya da makro olarak çıkarırdım. Ama hey, tüm kodlar mükemmel yazılmış değil. :)
Mart'ta Mysticial

5
@hippietrail Başlangıçta aynı şeyi merak ediyordum. Ancak 256 kullanırsanız, bunun 0.0 - 0.996yerine istenen boyuttan ölçeklendirilir 0.0 - 1.0. ( en büyük 8 bitlik tam sayı 0.996 = 255/256nerede 255)
Mysticial

7
Ve elbette, kendi sorumu cevaplamak için, diğer iki sayı standart C şamandıraları olarak temsil edilemez. 0.0039215689'un altındaki bir sonraki şamandıra 0.0039215684'tür.
Daniel Waechter

79

Bu çarpma, 0.0039215689f0 ila 255 aralığında tamsayı değerli bir renk yoğunluğunu 0 ila 1 aralığında gerçek değerli bir renk yoğunluğuna dönüştürür.

Ilmari Karonen'in belirttiği gibi, bu bir optimizasyon olsa bile, oldukça kötü ifade edilen bir optimizasyon. İle çarpmak çok daha açık olurdu (1.0f/255).


5
Ya da belki daha iyisi, sabit olarak mı tanımlanır?
Johny

9
@Johny Kesinlikle bir sabit olarak tanımlanır. Nokta sihirli bir değer değil.
David Heffernan
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.