상수 0.0039215689는 무엇을 나타 냅니까?


310

다양한 그래픽 헤더 파일 에서이 지속적인 팝업이 계속 나타납니다.

0.0039215689

아마도 색과 관련이있는 것 같습니다.

다음은 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

이 숫자는 무엇을 나타 냅니까? 왜 그것을 const로 선언하지 않는 것입니까?

Google에서 설명하는 내용을 찾을 수 없습니다.


16
소스 코드가 이것을 대신 쓰는 이유가 (1.f/255)있습니까?
MM

53
흠 ... 단지 매직 넘버를 방지 할 수있는 방법이 있다면 ...
폴 드레이퍼

12
1/255 == 0.00(3921568627450980)-parens는 반복을 의미합니다.
jfs

82

12
이유를 불문하고 목적을 기록하지 않고 마법 번호를 사용하는 것은 매우 불편합니다
Isaac Rabinovitch

답변:


378

0.0039215689대략 같습니다 1/255.

이것이 OpenGL임을 알면 성능이 중요 할 것입니다. 따라서 이것이 성능상의 이유로 수행되었다고 추측하는 것이 안전 할 것입니다.

역수를 곱하면 255를 반복해서 나누는 것보다 빠릅니다.


사이드 노트 :

왜 그러한 마이크로 최적화가 컴파일러에 남아 있지 않은지 궁금하다면, 그것은 안전하지 않은 부동 소수점 최적화이기 때문입니다. 다시 말해:

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

부동 소수점 반올림 오류로 인해.

따라서 최신 컴파일러는이 최적화를 수행하기에 충분히 똑똑 할 수 있지만 컴파일러 플래그를 통해 명시 적으로 말하지 않으면 수행 할 수 없습니다.

관련 : GCC가 a * a * a * a * a * a를 (a * a * a) * (a * a * a)로 최적화하지 않는 이유는 무엇입니까?


10
나는 실제로 그것을 처음 보았을 때 그것이 무엇인지 몰랐습니다. 그러나 그것이 사용 된 방식을 보았을 때, 그것이 곱셈에 의한 최적화라고 생각했습니다. 그래서 나는 계산기를 점검하고 충분히 확신했습니다.
Mysticial

55
나는 다음과 같이 쓰여질 것으로 기대했다 a = b * (1.0f / 255). 컴파일러는 여전히 일정한 폴딩을 수행합니까?
Ilmari Karonen

9
@IlmariKaronen 예, 그들은 여전히 ​​일정한 접힘을합니다. 실제로 템플릿 해상도와 같은 것들이 필요합니다. 그러나 나는 그것을 상수 또는 매크로로 뽑아 냈습니다. 그러나 모든 코드가 완벽하게 작성된 것은 아닙니다. :)
Mysticial

5
@hippietrail 처음에는 같은 일이 궁금했습니다. 그러나 256을 0.0 - 0.996사용하면 원하는 대신 확장됩니다 0.0 - 1.0. ( 0.996 = 255/256여기서 255가장 큰 8 비트 정수임)
Mysticial

7
물론 내 자신의 질문에 대답하기 위해 다른 두 숫자는 표준 C 부동 소수점으로 표현할 수 없기 때문입니다. 0.0039215689 아래의 다음 플로트는 0.0039215684입니다.
Daniel Waechter

79

이 곱셈은 0.0039215689f0에서 255 범위의 정수 값 색 강도를 0에서 1 범위의 실제 값 색 강도로 변환합니다.

일 마리 카로 넨 (Ilmari Karonen)이 지적했듯이 이것이 최적화라고해도 다소 잘못 표현 된 것입니다. 를 곱하는 것이 훨씬 더 명확합니다 (1.0f/255).


5
아니면 더 나은, 상수로 정의?
Johny

9
@Johny 확실히 상수로 정의되었습니다. 요점은 마법의 가치가 아닙니다.
David Heffernan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.