프로그램을 짜다 보면 기본적으로 알아야 하는 것이 각 변수들의 값의 범위 이다.
아래 내용들은 Watcom C와 MSDN Library에 나오는 변수들이다.
이 외에도 여러 유형이 있으나 현재 프로그래밍하면서 주로 사용하는 것은 int, double, float, DWORD, BYTE, UINT 정도가 되겠다.
그냥 사용할 때는 크게 의식하지 않아도 문제가 되지 않아 별 신경을 쓰지 않았었는데 오늘 debugging 중에 파형이 크게 변하는 부분이 발견되었다.
4.28 GHz 부근까지는 값이 정확하게 나왔지만 4.30GHz (=4300000000) 이상이 되는 주파수에서는 값이 맞다가 틀렸다가 하는 문제였다.
문제 발생 원인은 변수의 범위를 초과하는 주파수 값에 있었다.
화면 표시를 위해 정해 둔 여러 가지 제한 값 들 중에 정확한 값을 (Hz단위) 정하기 위해 DWORD로 변환한 부분이 있었는데 (double의 경우 유효숫자 문제로 인해 int 수준의 정확성을 맞추기가 어렵다.) DWORD의 저장 범위는 4294967295까지 이므로 4.30GHz가 되면 Overflow가 발생한 것이다.
결국 변수를 double로 고쳐서 수정하긴 했지만 이런 부분은 VS debuger 에서도 잡아 주지 않으므로 주의가 필요하다.
4300000000을 DWORD에 저장하면 Overflow가 발생하는데 그럼 저장되어 있는 값은 얼마가 될까?
4300000000을 16진수로 바꾸면 0x1004CCB00 이 된다. 여기서 Overflow 된 맨 앞의 1을 버리면 0x004CCB00 이 되어 5032704라는 값이 된다. 주파수로는 약 5.033MHz가 되겠다.
그럼, DWORD 보다 큰 값을 저장하려면 (1의 단위에서 정확성을 유지하면서) 어떤 방법이 있을까?
1) DWORD 변수 두개로 분리하여 계산하는 방법
2) DWORD64, UINT64 (64bit unsigned int)를 이용하는 방법
3) String을 이용하는 방법
등이 있겠다.
벌써 같은 실수를 두번이나 했으니 이것 참 입맛이 쓰다.
아래 내용들은 Watcom C와 MSDN Library에 나오는 변수들이다.
BYTE (=unsigned char) : 0~255
CHAR (=signed char) : -128~127
INT(=int) : 16 or 32 bit (machine dependent)
INT8 (=signed char) : -128~127
INT16 (=short) : -32768~32767
INT32 (=long) : -2147483648~2147483647
LONG (=long) : -2147483648~2147483647 (machine dependent)
SHORT (=short) : -32768~32767
TCHAR (=char or INT16) : 8bit or 16bit char, _UNICODE 정의에 따라 다름
UINT (=unsigned int) : 16 or 32bit (0~65535:16bit) (machine dependent)
UINT8 (=unsigned char) : 0~255
UINT16 (=unsigned short) : 0~65535
UINT32 (=unsigned long) : 0~4294967295
ULONG (=unsigned long) : 0~4294967295 (machine dependent)
USHORT (=unsigned short): 0~65535
float : 3.4x10^-38 ~ 3.4x10^38 (유효숫자 7자리)
double : 1.7x10^-308 ~ 1.7x10^308 (유효숫자 15자리)
long double : 3.4x10^-4932 ~ 3.4x10^4932 (유효숫자 19자리)
DWORD (=unsigned long) : 0~4294967295
이 외에도 여러 유형이 있으나 현재 프로그래밍하면서 주로 사용하는 것은 int, double, float, DWORD, BYTE, UINT 정도가 되겠다.
그냥 사용할 때는 크게 의식하지 않아도 문제가 되지 않아 별 신경을 쓰지 않았었는데 오늘 debugging 중에 파형이 크게 변하는 부분이 발견되었다.
4.28 GHz 부근까지는 값이 정확하게 나왔지만 4.30GHz (=4300000000) 이상이 되는 주파수에서는 값이 맞다가 틀렸다가 하는 문제였다.
문제 발생 원인은 변수의 범위를 초과하는 주파수 값에 있었다.
화면 표시를 위해 정해 둔 여러 가지 제한 값 들 중에 정확한 값을 (Hz단위) 정하기 위해 DWORD로 변환한 부분이 있었는데 (double의 경우 유효숫자 문제로 인해 int 수준의 정확성을 맞추기가 어렵다.) DWORD의 저장 범위는 4294967295까지 이므로 4.30GHz가 되면 Overflow가 발생한 것이다.
결국 변수를 double로 고쳐서 수정하긴 했지만 이런 부분은 VS debuger 에서도 잡아 주지 않으므로 주의가 필요하다.
4300000000을 DWORD에 저장하면 Overflow가 발생하는데 그럼 저장되어 있는 값은 얼마가 될까?
4300000000을 16진수로 바꾸면 0x1004CCB00 이 된다. 여기서 Overflow 된 맨 앞의 1을 버리면 0x004CCB00 이 되어 5032704라는 값이 된다. 주파수로는 약 5.033MHz가 되겠다.
그럼, DWORD 보다 큰 값을 저장하려면 (1의 단위에서 정확성을 유지하면서) 어떤 방법이 있을까?
1) DWORD 변수 두개로 분리하여 계산하는 방법
2) DWORD64, UINT64 (64bit unsigned int)를 이용하는 방법
3) String을 이용하는 방법
등이 있겠다.
벌써 같은 실수를 두번이나 했으니 이것 참 입맛이 쓰다.
Powered by ScribeFire.
'프로그래밍 이야기' 카테고리의 다른 글
| [연습문제3] 열혈강의 C++ 프로그래밍 (0) | 2007/12/21 |
|---|---|
| [OOP프로젝트 1단계] 열혈강의 C++ 프로그래밍 (0) | 2007/12/19 |
| visual studio 2005 express 설치 (2) | 2007/11/15 |
| [연습문제1] 열혈강의 C++ 프로그래밍 (0) | 2007/11/14 |
| 처음 부터 다시 (0) | 2007/11/13 |
| 변수의 범위 제한 (1) | 2007/10/29 |






