Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

문타쿠, 공부하다.

[독하게 시작하는 C 프로그래밍] 섹션 4. CPU 수준 자료형 본문

C언어/독하게 시작하는 C 프로그래밍

[독하게 시작하는 C 프로그래밍] 섹션 4. CPU 수준 자료형

개발새발 문타쿠 2023. 10. 9. 18:38

자료형에 대한 이해

자료형

  • 일정 길이의 메모리에 저장된 정보를 해석하는 방법
  • 저장된 정보, 즉 자료는 결국 숫자
  • C언어의 변수는 메모리를 사용하기 위한 문법으로 이해할 수 있음
  • 자료는 변수와 상수 두 종류가 있음

C언어 자료형

  • 정수형(부호유무, 크기)
  • 실수형(크기)
  • 유도형(*, [ ], 구조체, 공용체)
  • 함수형
  • 무치형(void)

상수와 변수 그리고 복잡성

상수의 정의 및 종류

  • 값이 확정되어 앞으로 변할 가능성이 없는 수
  • 리터럴 상수와 심볼릭 상수가 있는데, 일반적으로 상수 하면 리터럴 상수를 뜻함

리터럴 상수

  • 문자 상수(아스키 코드)
    • ex. 'A'
    • 컴퓨터에는 문자라는 개념이 존재하지 않아, 정수를 아스키 코드표에 매칭?된 문자로 랩핑하여 화면에 출력
  • 문자열 상수
    • ex. "Hello, World"
  • 정수 상수
    • ex. 3, 4L
  • 실수 상수
    • ex. 3.4f(단정도 = float), 123.45(배정도 = double)
    • 컴퓨터에서 실수라고 하면 기본적으로 배정도 형식, 즉 double을 뜻함

변수의 정의

  • 변수 = 메모리
  • 구체화하지 않았거나 앞으로 변경될 가능성이 있는 수(혹은 미지의 수)
  • 메모리를 사용하는 가장 일반적인 방법
  • 변수는 메모리가 가지는 특성(위치 정보인 주소, 공간의 크기)을 가짐

정수형

  • 1byte(= 8bit)는 컴퓨터에서 관리의 최소 단위
  • char와 int를 주로 사용하고 다른 자료형은 딱히..?
    • char는 주로 문자를 저장할 목적으로 사용
    • 컴퓨터에서 문자는 그저 숫자(정수)에 불과할 뿐, 아스키 코드에 의해 화면에 숫자가 아닌 특정 문자로 바뀌어 나타난다.

정수형 변수의 선언 및 정의

#include <stdio.h>

int main(void)
{
    char ch = 'A';
    short sData = 10;
    int nData = 10;
    long lData = 10L;
    long long int llnData = 10LL;

    unsigned char byNewData = 0;
    unsigned short sNewData = 65535U;
    unsigned int uNewData = 1U;
    unsigned long ulNewData = 1UL;
    unsigned long long int ullNewData = 1ULL;
    
    return 0;
}

2진수 덧셈과 뺄셈

보수

  • 2진수 0은 1로, 1은 0으로 뒤집으면 1의 보수
  • 1의 보수에 1을 더하면 2의 보수
  • 어떤 숫자에서 빼려는 숫자의 2의 보수를 더하면 2진수 뺄셈이 된다. (단, 자리올림은 절사)

ex) 12 - 7 = 5 (12₍₁₀₎ = 1100₍₂₎ / 7₍₁₀₎ = 0111₍₂₎ / 5₍₁₀₎ = 0101₍₂₎)

1단계. 0111의 1의 보수 -> 1000

2단계. 1000의 2의 보수 -> 1000 + 0001 = 1001

1100 + 1001 = 0101 (자리올림은 절사)


곱셈, 나눗셈, 시프트 그리고 하드웨어 손상

컴퓨터가 곱셈 하는 방법

  • 곱셈은 어떤 수(5)를 여러 번 더한 것과 같다.
    • ex. 5 * 2 = 5 + 5
    • ex. 5 * 4 = 5 + 5 + 5 + 5

  • 5를 2진수로 나타내면 0101
  • 0101을 left shift 연산으로 한 칸 밀면 1010 = 10, 즉 왼쪽으로 한 칸 이동하면 *2
  • 0101을 left shift 연산으로 두 칸 밀면 10100 = 20, 즉 왼쪽으로 두 칸 이동하면 *4
  • 그러면 곱하기 3은? -> 세 번 더한거라고 생각할 수 있으니 left 연산 한 번 하고(*2) 한 번 더해주면 ok

컴퓨터가 나눗셈 하는 방법

  • 나눗셈은 나누는 수(2) 보다 나머지가 작아질 때까지 여러 번 빼는 것과 같다.
    • ex. 7 / 2 => (7 - 2 = 5), (5 - 2 = 3), (3 - 2 = 1) => 몫: 3, 나머지: 1
    • ex. 7 / 4 => (7 - 4 = 3) => 몫:1, 나머지: 3

  • 7을 2진수로 나타내면 0111
  • 0111을 right shift 연산으로 한 칸 밀면 0011 = 3, 즉 오른쪽으로 한 칸 이동하면 / 2
  • 0111을 right shift 연산으로 두 칸 밀면 0001 = 1, 즉 오른쪽으로 두 칸 이동하면 / 4
  • 만약 7을 0으로 나누게 되면? -> 7 - 0 = 7, 7 - 0 = 7, ... 이 무한히 반복되게 되므로 어떤 수는 0으로 나눌 수 없다.

실수형 - 단정도, 배정도

  • 소수점 이하 정보를 표시하는 형식
  • 부동소수점 표현
  • 100.0, 10.0*10, 1.0*10²은 같은 값에 대한 표현
  • 두 정수 사이에는 무한에 가까운 많은 실수가 존재하기 때문에 일정 수준의 오류(부동소수점 오차)를 인정함
  • IEEE 754 표준
  • 단정도인 float은 부동소수점 오차가 크고 해상도도 떨어져서 요새 잘 안씀
  • 일반적으로 double을 사용함

실수형의 표현 범위

#include <stdio.h>
#include <float.h>

int main(void)
{
    double dData = 123.456;

    printf("%f\n", dData);
    printf("%E - %E\n", DBL_MIN, DBL_MAX);

    return 0;
}

실수형 - 부동소수점 오차

부동소수점은 근사값을 기반으로 작동하기 때문에 오차가 발생한다.

소숫점 이하 자릿수가 길어지면 오차가 있더라도 그 차이가 매우 근소하기에 무시해도 연산에 큰 영향을 주지 않다고 판단.

 

근사값이란?

근사값은 정확한 값을 완벽하게 표현하지 못하지만, 해당 값과 가능한 가까운 근사치 또는 추정값을 나타내는 수치를 말한다.

예를들어, 0.1f를 50번 더하면 어떤 값이 나올까?

5가 나올 것이라 생각했지만 실제로는 4.999998이 나왔다.

그렇다면 4.999998과 5를 동일하다고 봐야할까?

부동소수점 오차 때문에 같다고는 할 수 있겠지만, 적절하다고는 볼 수 없다.

-> float 단정도 말고 double 배정도를 사용해야 하는 이유