C++ 소수점 (Decimal Point)

2021. 3. 9. 19:36·C++/Syntax

소수점 (Decimal Point)

고정 소수점 (정수)

  • 부호화 절대치

    • 맨 왼쪽 비트가 부호를 결정하고, 나머지 비트는 일반 양수를 다루듯 계산한다.
    000 -> +0
    001 -> +1
    010 -> +2
    011 -> +3
    100 -> -0
    101 -> -1
    110 -> -2
    111 -> -3
    • 안쓰는 이유

      • 순환성이 떨어진다.(+3 다음이 -0)

      • 보수를 사용하면 감산기 없이 가산기만으로 뺄셈이 가능하다.

  • 1의 보수

    • 비트를 반전시켜 순환성을 가지도록 했다.(+3 다음이 -3)

    • 덧셈기로 뺄셈이 가능하다.

    000 -> +0
    001 -> +1
    010 -> +2
    011 -> +3
    100 -> -3
    101 -> -2
    110 -> -1
    111 -> -0
  • 2의 보수

    • 1의 보수를 취하고 1을 더하는 형태이다.

    • -0을 없애고 숫자를 하나 더 챙겼다.

    • 빨리 만드는 방법

      • 오른쪽부터 왼쪽 방향으로 1을 만날 때까지 그대로, 그 이후는 반전시키면 된다.
    000 -> +0
    001 -> +1
    010 -> +2
    011 -> +3
    100 -> -4
    101 -> -3
    110 -> -2
    111 -> -1

부동 소수점(실수)

  • 부호 비트, 지수부, 가수부로 구성된다.

    • single-precision(float) : 지수부(8비트), 가수부(23비트)

    • double-precision(double) : 지수부(11비트), 가수부(52비트)

  • (-1)^(부호비트) * (1.(가수부)) * 2^(지수부 - 127)의 값을 가진다.

    • double-precision의 경우 127(0b01111111)이 아닌 1023(0b01111111111)

    • 참고

      • 이기적 유튜브 : 설명이 상당히 꼼꼼하다.
  • 출력 시 precision 조절하기

    double d(0.1);
    
    std::cout << std::setprecision(16);
    std::cout << d << std::endl;  // 0.10000000000000001
  • 오차는 부동 소수점의 한계이다.

    double d(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1);
    
    std::cout << std::setprecision(16);
    std::cout << d << std::endl;  // 0.99999999999999989
  • 0으로 나누는 등 수학적인 오류가 발생할 가능성이 있는 경우

    • 실수를 0으로 나누면 inf이다.

    • 0을 0으로 나누면 nan이다.

    • <cmath> 라이브러리의 std::isinf, std::isnan으로 체크해야 한다.


float vs double

  • 의외로 연산 속도는 별 차이가 없다.

  • 메모리가 중요하다면 float, 정밀도가 중요하다면 double을 사용하는게 좋을 듯 하다.

  • 오차 예제

    #include <iostream>
    #include <iomanip>
    
    int     main()
    {
      using namespace std;
    
      const float f_begin = 1e9f;
      float f = f_begin;
      cout << setprecision(10000);
      cout << f << endl;    // 1000000000
      for (long long i = 0; i < 1e6; ++i)
        f += +1e0f;
      cout << f << "\n\n";  // 1000000000
    
      const double d_begin = 1e9f;
      double d = d_begin;
      cout << d << endl;    // 1000000000
      for (long long i = 0; i < 1e6; ++i)
        d += +1e0;
      cout << d << endl;    // 1001000000
    }
    • 근본적인 해결은 아니지만 임시로 해결하는 방법

      • 작은 연산은 따로 수행한 뒤 한번에 합치는 식으로 하면 된다.

        #include <iostream>
        #include <iomanip>
        
        int     main()
        {
            using namespace std;
        
            const float f_begin = 1e9f;
            float f = f_begin;
            cout << setprecision(10000);
            cout << f << endl;    // 1000000000
            float f2 = 0.0f;
            for (long long i = 0; i < 1e6; ++i)
                f2 += +1e0f;
            f += f2;
            cout << f << "\n\n";  // 1001000000
        }
저작자표시 (새창열림)

'C++ > Syntax' 카테고리의 다른 글

C++ 형 변환 (Type Casting)  (0) 2021.03.09
C++ Boolean  (0) 2021.03.09
C++ 자료형 (Data Type)  (0) 2021.03.09
C++ 전처리기 (Preprocessor)  (0) 2021.03.09
C++ Namespace  (0) 2021.03.09
'C++/Syntax' 카테고리의 다른 글
  • C++ 형 변환 (Type Casting)
  • C++ Boolean
  • C++ 자료형 (Data Type)
  • C++ 전처리기 (Preprocessor)
Caniro
Caniro
  • Caniro
    Minimalism
    Caniro
  • 전체
    오늘
    어제
    • 분류 전체보기 (317)
      • Algorithm (13)
        • 알기 쉬운 알고리즘 (10)
        • Search (1)
        • Sort (2)
      • Arduino (0)
      • C++ (185)
        • Class (46)
        • Exception (6)
        • Library (51)
        • Overloading (10)
        • SmartPointer (5)
        • Syntax (33)
        • TBC++ (23)
        • Templates (9)
        • VisualStudio (2)
      • Embedded (1)
      • Git (4)
      • Java (5)
      • Linux (16)
        • Error (1)
        • Linux Structure (11)
      • MacOS (7)
      • OS (1)
        • Concurrency (1)
      • Python (21)
        • Class (1)
        • Function (2)
        • Syntax (17)
      • Raspberrypi (9)
      • Review (1)
      • Utility (12)
        • VSCode (5)
        • VirtualBox (3)
      • Web (8)
        • Nginx (1)
        • React (3)
        • Django (1)
      • Windows (20)
        • Registry (3)
        • WSL (1)
        • DeviceDriver (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    맥북 카카오톡 알림 안뜸
    windows
    logi options
    java
    SunOS 5.1
    윈도우 명령어
    Workspace
    mspaint
    KakaoTalk
    제외
    vscode
    그림판
    MacOS
    dism
    spring
    EXCLUDE
    백기선
    Windows 11
    윈도우
    스프링 프레임워크 핵심 기술
    시스템 복구
    스프링
    로지텍 마우스 제스처
    Solaris 10
    알림
    SFC
    citrix workspace
    unix
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Caniro
C++ 소수점 (Decimal Point)
상단으로

티스토리툴바