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
[41149] Re:C++ Builder 의 임시객체에 대해 질문있습니다~ ^^;
evergreen [heredity] 842 읽음    2005-07-21 13:34
안녕하세요. heredity입니다.

질문하신 내용은 유효자리를 벗어나는 실수 연산이 그 원인인 것으로 추정됩니다.
point.x * cos0의 결과 값인 3.06151588455594E-16F는 상당히 작은 값인데,
double형이 이 값만을 가질 경우 실수 유효 범위(자리)안에 들어가기 때문에 표현(저장) 가능하나
실수 -5.0과 더해지면서 그 값이 유효자리를 벗어나게 되며,
double 변수에 보관하면 -5로 기록됩니다(이 부분은 실제로 해보지 않으면 잘 이해가 안 될 수도 있습니다.)

반면 실행 결과를 double에 보관하기전 정수화 시키면
-4.9999999...를 정수화 해서 -4가 되는 것으로 추정됩니다.
불행히도 이 연산에 대한 실행코드는 Co-processor에게 전달되어 처리되므로
직접 확인은 불가능 했으나 아래의 예를 보면 그 원인을 짐작 할 수 있으리라 봅니다.

    double dblFive = -5;
    double dblCos  = 3.06151588455594E-16F;
    double dblAdd  = dblFive + dblCos;

    int nX1 = dblFive + dblCos;                    // nX1  = -4, 실행 중간 결과를 확인해 보면 좋으련만...
    int nX2 = dblAdd;                              // nX2  = -5
    int nX3 = (int) (dblFive + dblCos);            // nX3  = -4

    double dblM = -5 + 3.06151588455594E-16F;      // dblM = -5;

소스 우측 부분에 결과값을 표시하여 두었으니 확인하시기 바랍니다.
행복하세요.


WARSHIP 님이 쓰신 글 :
:

: class TPoint
: {
: public:
:     TPoint() {}
:     TPoint(int _x, int _y) : x(_x), y(_y) {}
:     TPoint(POINT& pt)
:     {
:         x = pt.x;
:         y = pt.y;
:     }
:     operator POINT() const
:     {
:         POINT pt;
:         pt.x = x;
:         pt.y = y;
:         return pt;
:     }
:     int  x;
:     int  y;
: };
:
: template < typename PT_Type >
: struct Special_Rotate /* Rotate point at special origin */
: {
:     static PT_Type rotate( PT_Type &point, double &angle , PT_Type &origin )
:     {
:        
:         double cos0=cos(angle) , sin0=sin(angle);
:        
:         // Case 1
:         double nx,ny;
:         nx = (point.x * cos0) + (point.y * -sin0) + ( -origin.x * cos0 ) + (  origin.y * sin0 ) + origin.x;
:         ny = (point.x * sin0) + (point.y *  cos0) + ( -origin.x * sin0 ) + ( -origin.y * cos0 ) + origin.y;
:         PT_Type pt1(nx,ny);
:
:         // Case 2
:         PT_Type pt2;
:         pt2.x = (point.x * cos0) + (point.y * -sin0) + ( -origin.x * cos0 ) + (  origin.y * sin0 ) + origin.x;
:         pt2.y = (point.x * sin0) + (point.y *  cos0) + ( -origin.x * sin0 ) + ( -origin.y * cos0 ) + origin.y;
:        
:         printf(" Case 1 : [%2d,%2d]\n",pt1.x , pt1.y);
:         printf(" Case 2 : [%2d,%2d]\n",pt2.x , pt2.y);
:         return pt1;
:     }
: };
:
: int main()
: {
:     TPoint a,b(5,5);
:     a = Special_Rotate<TPoint>::rotate(b,M_PI_2,TPoint(0,0));
:     return 0;
: }
:

:
: 위의 화일을 컴파일 하면
: 결과는 아래와 같습니다.
:
: ---------- Excute ----------
:  Case 1 : [-5, 5]
:  Case 2 : [-4, 5]
: 출력 완료 (0초 경과) - 정상 종료
:
: 1번의 경우에는 계산값이 double형 변수에 담겼다가 형변환이 되면서 pt1으로 저장되구요.
: 2번의 경우에는 계산값이 double형 임시변수(컴파일러가 만들어주는?)에서 바로 형변환이 되면서 pt2로 들어가
: 는걸로 알고 있는데요 ( More Effective c++ .. )
: 같은 계산식인데도 불구하고 두결과가 저렇게 차이가 나네요.
:
: 임시변수나 객체는 컴파일러가 최적화 할수 있으니 되도록이면 임시변수나 객체를 쓰라고 읽은 기억도 있는데
: 위와 같은 결과가 나오니까 좀 아이러니 하고 , 이해가 안되서 이렇게 질문을 올립니다.
: 특별한 컴파일 옵션을 주어야 하는지. 아니면 굳이 Case1번처럼 코딩을 해야 하는지
: 궁금하네요. 그럼 좋은 하루 보내시구요~ 답변좀 부탁드립니다. 의견도 좋습니다 ^^;

+ -

관련 글 리스트
41138 C++ Builder 의 임시객체에 대해 질문있습니다~ ^^; WARSHIP 1006 2005/07/20
41149     Re:C++ Builder 의 임시객체에 대해 질문있습니다~ ^^; evergreen 842 2005/07/21
41152         답변감사합니다.~ ^^; WARSHIP 677 2005/07/21
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.