C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[69531] Re:Re:Re:Re:Re:Re: 논리적인 오류가 맞습니다
지나다가 [] 2736 읽음    2013-05-27 14:42
DWORD dwStart = 100;
DWORD dwCur = 200;
DWORD dwDelta = 0;

라고 할 때

dwDelta = dwCur - dwStart ;

dwDelta 값이 100 이 되겠지요

그러나

dwCur 가 최대값을 넘어가서 0 이 되었다면

dwDelta = dwCur - dwStart ;

dwDelta 값은 4294967196 이 됩니다.

오버플로가 발생했기 때문이죠.

따라서 원하던 것과는 엉뚱한 결과가 발생하게 됩니다.

중급자들도 자주 실수하는 프로그래밍의 기초적인 부분이죠.


김시환 님이 쓰신 글 :
: 논리적인 오류는 아닙니다.
: 왜냐하면 GetTickCount() 함수는 49.7일 후 즉 1193시간후 부터는 0부터 다시 시작하는 것으로 설명되어 있습니다.
:
: 따라서 아래 코드 중에서 m_dfStartTime 변수를 계속 갱신하고 있기 때문에 1193시간 후에라도 0부터 시작하는 값으로 다시
: 시작할 수 있는 것이라 생각이 됩니다.
:
: 물론 1193시간이 넘어가는 순간에 한번정도는 까먹을 수 있어도 그 이후로는 다시 갱신되기 때문에 정상적으로 진행이 되어야
: 한다는 것입니다.
:
: 저도 처음에 오버플로우를 생각했었지만 함수 설명을 읽어보면 오버플로우 문제도 아닌것으로 보입니다.
:
:
:
: 흐흠 님이 쓰신 글 :
: : GetTickCount() 으로 처리할 수 있는 Time Duration은 1193 시간에 불과 하므로
: : 1400 시간이 지났다면 오버 플로우 상태가 되니까 마이너스 연산으로 뒤집어지는
: : 결과가 발생함. 오버 플로우 상태를 고려하지 않은 프로그램의 논리적인 오류임.
: : 오버 플로우를 고려하려면 매번 최상위 비트를 체크해서 반대로 연산을 뒤집어주는
: : 코드가 들어가야 함. 프로그래밍의 아주 기초적인 부분임.
: :
: : GetTickCount64() 를 이용하더라도 Time Duration 만 커질 뿐 근본적인 해결책이 되지는 못함.
: :
: : 따라서 GetTickCount() 이나 GetTickCount64() 함수를 이용하는 것 보다는.
: :
: : WaitForSingleObject() 를 이용해서 스레드가 10초 동안 슬립 상태로 들어가게
: : 코딩을 하는 게 더 효율적인 방법임.
: :
: :
: :
: : 이경문 님이 쓰신 글 :
: : : GetTickCount()의 return값은 DWORD(unsigned int 32 bit) 이죠.
: : : DWORD의 range(msec 단위)의 최대값을 날짜로 환산해 보세요.
: : :
: : : 김시환 님이 쓰신 글 :
: : : : 답변은 감사합니다.
: : : : 그런데 해결방법도 중요하지만 원인을 좀 알고 싶은데요.. 해결하는거야 어떻게든 가능하지만 원인을 아는게 프로그램하는 사람으로서 더 필요한 정보일것 같아서요..
: : : :
: : : : Lyn 님이 쓰신 글 :
: : : : : GetTickCount64로 바꾸면 문제 깔끔하게 해결 ...
: : : : :
: : : : : 김시환 님이 쓰신 글 :
: : : : : :
: : : : : : 샘플시료의 Aging을 위해 장비를 오랜시간 돌리는 프로그램을 작성하고 샘플시료를 테스트하고 있습니다.
: : : : : : Aging 중간 중간에 Aging 상태에 대한 내용을 읽어와서 데이타를 화면에 보여주는 프로그램입니다.
: : : : : : Aging 을 하면서 데이타를 읽어내는 것은 Thread를 사용하고 있습니다.
: : : : : :
: : : : : :     while(!Terminated)
: : : : : :     {
: : : : : :         m_dfDelayTime = (GetTickCount() / 1000.0) - m_dfStartTime ;
: : : : : :
: : : : : :         if(m_dfDelayTime > 10)      // 10초에 한번씩 시스템데이타를 읽어 온다.
: : : : : :         {
: : : : : :               Data_Read() ;
: : : : : :        
: : : : : :               m_dfStartTime = GetTickCount() / 1000.0 ;
: : : : : :         }
: : : : : :
: : : : : :          if(user_stop == true) this->Terminate() ;
: : : : : :
: : : : : :          if( g_dfTestTime <= 0) Sample_Test()
: : : : : :     }
: : : : : :
: : : : : : 대충 위의 코드와 같은 동작이 쓰레드에서 구동중입니다. 지금 거의 1400 시간 정도 돌아가고 있는데.. 문제는 지금까지 잘 실행되던 Data_Read() 함수가 호출이 안돼고 있다는 것입니다. 그래서 처음에는 쓰레드가 뻣었나 싶어서 시스템을 정지시키려고 했다가 혹시나 하는 맘으로 Sample_Test() 라는 함수가 진행되는지 지켜보았습니다. 아니나 다를까 Sample_Test() 함수는 정상적으로 실행이 되고 있었습니다.
: : : : : :
: : : : : : 여기서 의문
: : : : : :
: : : : : : 10초에 한번씩 시스템 데이타를 읽어오기 위한 함수가 왜 호출이 안돼느냐 하는 문제입니다.
: : : : : : 처음에는 m_dfStartTime 를 초기화하지 않았다고 생각했는데 코드를 보니 그것도 아니더군요..
: : : : : : GetTickCount() 함수를 보면 49.7 일 후에 다시 0으로 회귀하는 것으로 되어 있어서 m_dfStartTime 변수를 계속해서 갱신해 주면 문제가 없을것 같은데.. 뭐가 문제일까요??
: : : : : :
: : : : : : 테스트 진행중이라 디버깅도 못해 보겠고.. 이 문제를 해결하려고 다른 PC를 근 50일을 돌려 볼수도 없고.. 참 애매 합니다.
: : : : : :
: : : : : :

+ -

관련 글 리스트
69522 GetTickCount() 함수에 대한 의문점... 김시환 2784 2013/05/27
69606     Re:GetTickCount() 함수에 대한 의문점... 김동원 2945 2013/06/07
69538     많은 토론끝에 문제점을 찾았습니다. 자답입니다. 김시환 3045 2013/05/27
69541         Re:많은 토론끝에 문제점을 찾았습니다. 자답입니다. 김태선 2820 2013/05/27
69540         Re: 음수가 나왔다는 것 자체가 오버플로어 때문이죠 99 2842 2013/05/27
69543             Re:Re: 음수가 나왔다는 것 자체가 오버플로어 때문이죠 김시환 2912 2013/05/28
69523     Re:GetTickCount() 함수에 대한 의문점... Lyn 3518 2013/05/27
69524         Re:Re:GetTickCount() 함수에 대한 의문점... 김시환 2736 2013/05/27
69525             Re:Re:Re:GetTickCount() 함수에 대한 의문점... 이경문 2602 2013/05/27
69527                 Re:Re:Re:Re: 논리적인 오류임 흐흠 2357 2013/05/27
69533                     Re:Re:Re:Re:Re: 논리적인 오류임 - GetTickCount64() 에 대해.. 장성호 4677 2013/05/27
69536                         Re:Re:Re:Re:Re:Re: 논리적인 오류임 - GetTickCount64() 에 대해.. 김시환 3181 2013/05/27
69534                         Re:Re:Re:Re:Re:Re: 논리적인 오류임 - GetTickCount64() 에 대해.. 지나다가 2750 2013/05/27
69528                     Re:Re:Re:Re:Re: 논리적인 오류임 김시환 2510 2013/05/27
69531                         Re:Re:Re:Re:Re:Re: 논리적인 오류가 맞습니다 지나다가 2736 2013/05/27
69535                             Re:Re:Re:Re:Re:Re:Re: 논리적인 오류가 맞습니다 김시환 2293 2013/05/27
69537                                 Re:Re:Re:Re:Re:Re:Re:Re: 논리적인 오류가 맞습니다 이경문 2597 2013/05/27
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.