#if 0//////////////////////////////////////////////////////////////////////////
문제) 다음 식을 실수를 전혀 사용하지 말고 정수로만 계산을 하며,
정수 나눔셈도 사용하지 않고 같은 결과를 얻으시요. (비트연산 활용)

Y=0.299*R + 0.587*G + 0.114*B (칼러를 그레이로 변환하는 공식임)

R=123, G=100, B=230 일 때 Y=121 입니다.
#endif/////////////////////////////////////////////////////////////////////////

#pragma warning(disable:4996)   //보안에 취약하다는 잔소리를 없앰
#define WIN32_LEAN_AND_MEAN     //수많은 윈도우즈 헤더중에 최소한만 사용하겠다 (컴파일 속도 빠름)
#include <Windows.h>
#include <stdio.h>

//-----------------------------------------------------------------------------
//      GetTickCount() 보다 정밀한 ms를 가져옴
//-----------------------------------------------------------------------------
DWORD GetPerformanceTime()
    {
    LARGE_INTEGER PerformCnt, PerformFreq;
    QueryPerformanceCounter(&PerformCnt);
    QueryPerformanceFrequency(&PerformFreq);
    return (DWORD)(PerformCnt.QuadPart*1000/PerformFreq.QuadPart);
    }

int ToGrayReal(int R, int G, int B)
    {
    return (int)(0.299*R + 0.587*G + 0.114*B);
    }

int ToGrayInt(int R, int G, int B)
    {
    return (306*R + 601*G + 117*B)>>10;
    }

void main()
    {
    int I;
    DWORD Time;

    printf("Real Y=%d\\n", ToGrayReal(123, 100, 230));
    printf("Int  Y=%d\\n", ToGrayInt(123, 100, 230));

    Time=GetPerformanceTime();
    for (I=0; I<1920*1080*100; I++) ToGrayReal(123, 100, 230);
    printf("Real Time: %d ms\\n", GetPerformanceTime()-Time);

    Time=GetPerformanceTime();
    for (I=0; I<1920*1080*100; I++) ToGrayInt(123, 100, 230);
    printf("Int  Time: %d ms\\n", GetPerformanceTime()-Time);
    }

#if 0
//옵티마이즈 끄고 컴파일 했을 때 결과
Real Y=121
Int  Y=121
Real Time: 1099 ms
Int  Time: 602 ms

FullHD 이미지 100장을 그레이로 바꾸는 시간을 재보니 거의 2배 차이가 납니다.
실수연산을 하드웨어로 하는 PC도 이럴진데
실수연산처리기가 없는 마이컴이라면 엄청나게 차이나겠죠.

풀이
====

주어진 수식을 정수식으로 변환을 하면
Y=(299*R + 587*G + 114*B)/1000;

정수 나눗셈이 한번 들어가므로 이것을 제거하기 위해
분자 분모에 /1000*1024 를 합니다

Y=(306*R + 601*G + 117*B)/1024;

/1024는 >>10 이므로
Y=(306*R + 601*G + 117*B)>>10;

#endif