Cosa rappresenta la costante 0,0039215689?


310

Continuo a vedere questo costante pop-up in vari file di intestazione grafica

0.0039215689

Sembra che abbia qualcosa a che fare con il colore forse?

Ecco il primo successo su 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

Cosa rappresenta questo numero? Perché nessuno sembra dichiararlo come const?

Non sono riuscito a trovare nulla su Google che lo spiegasse.


16
C'è qualche motivo per cui il codice sorgente dovrebbe scrivere questo invece di (1.f/255)?
MM

53
Mmmm ... se solo ci fosse un modo per evitare i numeri magici ....
Paul Draper,

12
1/255 == 0.00(3921568627450980)- parens significa ripetizione.
jfs,

82
Con il tuo prossimo numero magico, prova a chiedere a Wolfram Alpha
AakashM il

12
qualunque sia la ragione, usare un numero magico senza documentarne lo scopo è molto strano
Isaac Rabinovitch

Risposte:


378

0.0039215689è approssimativamente uguale a 1/255.

Visto che si tratta di OpenGL, le prestazioni sono probabilmente importanti. Quindi probabilmente è sicuro indovinare che questo è stato fatto per motivi di prestazioni.

Moltiplicare per il reciproco è più veloce della divisione ripetuta per 255.


Nota a margine:

Se ti stai chiedendo perché una tale micro-ottimizzazione non sia lasciata al compilatore, è perché si tratta di un'ottimizzazione a virgola mobile non sicura. In altre parole:

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

a causa di errori di arrotondamento in virgola mobile.

Quindi, mentre i compilatori moderni possono essere abbastanza intelligenti da fare questa ottimizzazione, non sono autorizzati a farlo a meno che tu non glielo dica esplicitamente tramite un flag di compilatore.

Correlati: Perché GCC non ottimizza a * a * a * a * a * a a (a * a * a) * (a * a * a)?


10
In realtà non sapevo cosa fosse la prima volta che l'ho visto. Ma visto il modo in cui era usato, sospettavo fosse l'ottimizzazione moltiplicata per reciprocità. Quindi ho controllato il mio calcolatore e abbastanza sicuro - ho indovinato bene.
Mistico il

55
Mi sarei aspettato di vederlo scritto come a = b * (1.0f / 255); i compilatori continuano a piegare costantemente, no?
Ilmari Karonen,

9
@IlmariKaronen Sì, continuano a piegare costantemente. In realtà è richiesto per alcune cose come risoluzioni di template e simili. Ma l'avrei appena estratto come una costante o una macro. Ma hey, non tutto il codice è scritto perfettamente. :)
Mistico il

5
@hippietrail Inizialmente, mi chiedevo la stessa cosa. Ma se usi 256, ridimensionerebbe 0.0 - 0.996invece quello desiderato 0.0 - 1.0. ( 0.996 = 255/256dove 255è il numero intero a 8 bit più grande)
Mistico

7
E naturalmente, per rispondere alla mia domanda, è perché gli altri due numeri non possono essere rappresentati come float C standard. Il float successivo sotto 0,0039215689 è 0,0039215684.
Daniel Waechter,

79

Questa moltiplicazione 0.0039215689fconverte un'intensità di colore con valore intero nell'intervallo da 0 a 255 in un'intensità di colore con valore reale nell'intervallo da 0 a 1.

Come sottolinea Ilmari Karonen, anche se si tratta di un'ottimizzazione è piuttosto mal espressa. Sarebbe molto più chiaro moltiplicare per (1.0f/255).


5
O forse meglio, definito come costante?
Johny,

9
@Johny Certamente definito come costante. Il punto non è un valore magico.
David Heffernan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.