Was bedeutet die Konstante 0,0039215689?

310

Ich sehe diese Konstante immer wieder in verschiedenen Grafik-Header-Dateien

0.0039215689

Es scheint vielleicht etwas mit Farbe zu tun zu haben?

Hier ist der erste Treffer bei Google :

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

Was bedeutet diese Nummer? Warum scheint es niemand als Konstante zu deklarieren?

Ich konnte bei Google nichts finden, was das erklärt hätte.

zerquetschen
quelle
16
Gibt es einen Grund, warum der Quellcode dies anstelle von schreiben würde (1.f/255)?
MM
53
Mmmm ... wenn es nur eine Möglichkeit gäbe, magische Zahlen zu vermeiden ...
Paul Draper
12
1/255 == 0.00(3921568627450980)- Parens bedeuten Wiederholung.
JFS
82
Fragen Sie
AakashM am
12
Was auch immer der Grund sein mag, eine magische Zahl zu verwenden, ohne ihren Zweck zu dokumentieren, ist sehr unkühl
Isaac Rabinovitch

Antworten:

378

0.0039215689ist ungefähr gleich 1/255.

Da dies OpenGL ist, ist die Leistung wahrscheinlich wichtig. Es ist also wahrscheinlich sicher zu erraten, dass dies aus Leistungsgründen geschehen ist.

Das Multiplizieren mit dem Kehrwert ist schneller als das wiederholte Teilen durch 255.


Randnotiz:

Wenn Sie sich fragen, warum eine solche Mikrooptimierung nicht dem Compiler überlassen bleibt, liegt dies daran, dass es sich um eine unsichere Gleitkommaoptimierung handelt. Mit anderen Worten:

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

aufgrund von Gleitkomma-Rundungsfehlern.

Moderne Compiler sind zwar intelligent genug, um diese Optimierung durchzuführen, sie dürfen dies jedoch nur tun, wenn Sie sie ausdrücklich über ein Compiler-Flag dazu auffordern.

Verwandte: Warum optimiert GCC nicht a * a * a * a * a * a bis (a * a * a) * (a * a * a)?

Mystisch
quelle
10
Ich wusste eigentlich nicht, was es war, als ich es zum ersten Mal sah. Aber angesichts der Art und Weise, wie es verwendet wurde, vermutete ich, dass es sich um die Multiplikation mit gegenseitiger Optimierung handelte. Also habe ich meinen Taschenrechner eingecheckt und sicher genug - ich habe richtig geraten.
Mysticial
55
Ich hätte erwartet, dass es so geschrieben wird a = b * (1.0f / 255); Compiler falten immer noch ständig, nicht wahr?
Ilmari Karonen
9
@IlmariKaronen Ja, sie falten immer noch ständig. Es ist tatsächlich für einige Dinge wie Vorlagenauflösungen und dergleichen erforderlich. Aber ich hätte es einfach als Konstante oder Makro herausgezogen. Aber hey, nicht jeder Code ist perfekt geschrieben. :)
Mysticial
5
@ Hippietrail Anfangs habe ich mich das Gleiche gefragt. Wenn Sie jedoch 256 verwenden, wird 0.0 - 0.996stattdessen die gewünschte Skalierung vorgenommen 0.0 - 1.0. ( 0.996 = 255/256wo 255ist die größte 8-Bit-Ganzzahl)
Mysticial
7
Und um meine eigene Frage zu beantworten, liegt es natürlich daran, dass die beiden anderen Zahlen nicht als Standard-C-Floats dargestellt werden können. Der nächste Float unter 0,0039215689 ist 0,0039215684.
Daniel Waechter
79

Diese Multiplikation durch 0.0039215689fUmwandlung einer ganzzahligen Farbintensität im Bereich von 0 bis 255 in eine realwertige Farbintensität im Bereich von 0 bis 1.

Wie Ilmari Karonen betont, ist dies eine ziemlich schlecht zum Ausdruck gebrachte Optimierung. Es wäre so viel klarer, mit zu multiplizieren (1.0f/255).

David Heffernan
quelle
5
Oder vielleicht besser als konstant definiert?
Johny
9
@ Johny Sicher als Konstante definiert. Der Punkt ist kein magischer Wert.
David Heffernan