#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