티스토리 뷰

2.3 정수의 산술연산

두 개의 양수를 더해서 음수가 나오는 경우와 x<y를 했을 때의 결과가 x-y<0과 다른 결과를 보일 때가 있다. 이 특징들은 컴퓨터 산술연산의 유한한 본성에 의해 생겨난 결과들이다. 컴퓨터 산술연산의 미묘한 느낌을 이해하면 보다 안정적인 코드를 작성할 수 있다.

2.3.1 비부호형 덧셈

  • 두 개의 비음수 x, y, 0 <= x, y < w^2가 있다고 하자. 이들 각각은 w비트 비부호형 수로 표시될 수 있다. 이들의 합을 계산하면 가능한 범위는 0 <= x + y <= 2^(w+1) - 2를 갖는다. 이 합을 표시하기 위해서는 w+1개의 비트가 필요하게 된다. 만일 w+1비트 수로 합을 유지하고 다른 값과 더하려 하다면, w+2 비트가 필요하며, 나머지도 같은 방식으로 생각할 수 있다. 이와 같은 워드크기증가는 산술연산의 결과를 완벽하게 표시하려면 필요한 워드 크기를 제한할 수 없다는 것을 의미한다.
  • 일반적으로 프로그래밍 언어들은 고정길이 산술연산을 지원하며 덧셈곱셈같은 연산은 정수에 대응하는 일반적인 연산들과는 다르다.
    • 0 <= x, y < 2^w 인 변수 x, y에 대해 x + y 정수합을 w비트 길이로 절삭한 후에 다시 비부호형 정수로 나타내는 연산으로 정의한다.
    • 비부호형 산술 연산은 나머지 연산 modular의 한가지 형태로 볼 수 있으며, x + y의 비트 수준 표현에서 자리값이 2^(w - 1)보다 큰 비트들을 단순히 삭제하여 w^2의 나머지를 구해서 계산한다.
    • 예를 들어 x = 4, y = 12를 4비트로 표시할 때 이들은 각각 10011100으로 나타낸다. 이들의 합은 21로, 5비트 표현으로는 10101이다. 그러나 만일 상위 비트를 버린다면 0101이 되고, 이것은 십진수로 5이다. 이것은 21 mod 16 = 5와 일치한다.
  • 산술연산에서 완전한 정수 결과가 그 데이터 타입의 제한된 워드 길이로 나태닐 수 없을 때, 이 연산은 오버플로우한다.고 한다.

2.3.2 2의 보수의 덧셈

  • 합 x+y가 Tmax를 초과할 때 양의 오버플로우가 발생했다고 한다. 이 경우 절삭한 효과는 합에서 2^w를 뺀 것 과 같다.
  • 합 x+y가 Tmin보다 작으면 음의 오버플로우가 발생했다고 한다. 이 경우, 절삭한 효과는 합에 2^w를 더한 것과 같다.
  • 두 개의 w비트 2의 보수 합은 비부호형 합과 정확히 동일한 비트수준 표시를 갖는다. 사실, 대부분의 컴퓨터는 비부호형이건 부호형 덧셈이건 동일한 기계어 인스트럭션을 사용한다.

2.3.4 비부호형 곱셈

  • 최대 2^w비트가 필요하다.
    • C언어에서 부호형 곱셈은 일반적으로 2w 비트를 w비트로 절삭하는 형태로 실행한다.
    • 2의 보수를 w비트로 절삭하는 것은 먼저 그 값을 2^w로 나눈 나머지를 취하고 비부호형에서 2의 보수형태를 변환하는 것과 같다.
  • 2의 보수 곱셈
    • 곱셈 연산을 비트 수준으로 표시하는 것은 비후호형이나 부호형 곱셈에서 모두 동일하다.

2.3.6 상수를 사용한 곱셈

  • 컴파일러에서 수행되는 중요한 최적화는 상수를 곱하게 되는 경우들을 쉬프트와 덧셈의 조합으로 대체한다.
    • 11은 w=4인 경우 1011로 표시할 수 있다. 이것을 왼쪽으로 k=2 쉬프트하면 6비트 벡터 101100이 되며, 이것은 비부호형 수 11 x 4 = 44를 인코딩한 것이다.
  • 2의 제곱을 곱하면 비부호형이건 2의 보수 산술연산이건 오버플로우가 발생할 수 있다는 점을 유의해야 한다.

2.3.8 정수 산술연산에 대한 마지막 고찰

  • 정수 산술연산은 실제로는 modular 산술연산의 형태로 수행된다.
  • 숫자를 표현하기 위해 유한한 길이의 워드를 사용하기 때문에 가능한 값의 범위가 제한되며, 연산의 결과가 오버플로우 될 수 있다.
  • 덧셈, 뺄셈, 곱셈, 나눗셈의 경우에도 오퍼랜드가 2의 보수이건 비부호형이건 동일하거나 매우 유사한 비트수준 동작을 갖는다.

2.4 부동소수점

부동소수점 표현은 V = x x 2^y형태의 소수를 인코딩한다. 이 방식은 매우 큰 수와 관련된 계산을 할 때와 0에 매우 가까운 수를 계산할 때 유용하다.

2.4.1 비율 이진수(Fractional Binary Numbers)

먼저 십진수를 통해 생각해보면 십진 소수점 부호 .에 상대적으로 자리값이 정해진다. 즉 .를 기준으로 좌측의 숫자들은 10의 비음수 제곱을 자리값으로 가지며, 우측의 숫자들은 음의 제곱을 자리값으로 갖게 되어 소수 값을 만든다.
이와 동일하게 이진 소수점 좌측의 숫자들은 2^i 형태의 자리값을 가지며, 우측의 값은 1/2^i 자리값을 갖는다. 부호 .는 이제 이진 소수점이 되고, 좌측의 비트들은 비음수의 2의 제곱을 자리값으로 가지며, 우측은 2의 음의 제곱을 자리값으로 갖는다. 예를 들어 101.11는 1 x 2^2 + 0 x 2^1 + 1 x 2^0 + 1 x 2^-1 + 1 x 2^-2 이 된다. 마찬가지로 이진 소수점을 한 자리 우측으로 이동하면 수를 2로 곱한 효과를 얻는다.

2.4.2 IEEE 부동소수점 표시

IEEE 부동 소수점 표준은 수를 V = (-1)^s X M X 2^E 형태로 나타낸다.

  • 부호 s는 숫자가 음수인지(s=1) 양수인지(s=0)를 결정한다. 여기서 0을 나타내기 위한 부호 비트는 특별하게 다룬다.
  • 유효숫자 M은 비율 이진수이다.
  • 지수 E는 2의 제곱으로 자리값을 제공한다. (음수 제곱도 가능하다.)

부동소수점 수의 비트 표시는 이 값들을 인코딩하기 위해 세 개의 필드로 나누어진다.

  • 한 개의 부호 비트 s는 부호 s를 직접 인코딩한다.
  • k비트 지수 필드 exp는 지수 E를 인코딩한다.
  • n비트 비율 필드는 유효숫자 M을 인코딩한다. 그러나 인코딩 된 값은 지수 필드가 0인지 여부에도 관계된다.

Case 1: 정규화 값 (Normalized Values)

  • 가장 일반적인 경우
  • exp의 비트 패턴이 모두 0은 아니며, 모두 1이 아니어야 한다.
  • 지수 필드는 부호형 정수를 Bias 형태로 나타내도록 해석한다. 즉 지수 값은 E = e - Bias 이며, 여기서 e는 비부호형 수로 비트 패턴을 가진다.
  • 비율 필드 frac은 이진 소수점이 가장 중요한 비트의 맨 좌측에 위치한다는 것을 의미한다.
  • 유효숫자 M = 1 + f 로 정의된다. 이를 때로는 암시적 선두 1표시 라고 부르기도 한다. 이러한 표시는 정밀도를 위해 추가 비트 한 개를 무료로 얻으려는 기법이다.

Case 2: 비정규화 값 (Denomalized Values)

  • 지수 필드가 모두 0일 때 나타낸 수는 비정규화 형태를 갖는다.
  • 지수 값은 E = 1 - Bias
  • 유효숫자 M = f. 즉, 암시적 선두 1이 없는 비율 필드값이다.
  • 정규화 숫자로는 항상 M >=1 이므로 0을 나타낼 수 없기 때문에 이들은 숫자 0을 표시하는 방법을 제공한다.
  • 비정규화 숫자들의 기능은 0.0에 매우 가까운 값들을 나타내는 것이다.
    • 이들은 점증적 언더플로우라고 알려진 특성을 제공한다.
    • 이 특성은 가능한 숫자 값들이 0.0 근처에서 같은 간격을 갖는다는 것을 의미한다.

Case 3: 특수 값 (Special Values)

  • 지수 필드가 모두 1인 경우
  • 비율 필드가 모두 0이면 결과값은 무한대를 나타낸다.
    • s = 0이면 양의 무한대
    • s = 1이면 음의 무한대
  • 비율 필드가 0이 아니면, 결과값은 NaN
  • 이들은 초기화되지 않은 데이터를 표시할 때와 같은 일부 응용에서 유용할 수 있다.

2.4.4 근사법 (Rounding)

부동소수점 산술연산은 표시방법이 제한된 범위와 정밀도를 갖기 때문에 실제 연산의 근사값을 사용할 수 밖에 없다. 때문에 어떤 x에 대해 원하는 부동소수점 형식으로 표시할 수 있는 가장 유사한 값 x'를 체계적으로 계산하는 방법을 필요로 한다. 이것은 근사 연산을 의미한다.
중요한 것은 어떤 값이 정확히 중간에 위치할 때 이것을 어느 방향으로 근사하는가이다. 예를 들어 $1.50를 가지고 있고, 이것을 가장 가까운 달러로 근사하고 싶다면 $1과 $2 중 무엇이 좋은지의 문제이다. 다른 접근방법은 실제 숫자에 대해 최소와 최대 한계를 정하는 것이다. IEEE 부동소수점 형식은 네가지 근사 모드를 정의하고 있다.

  • Round-to-even(짝수 근사법): 근사값의 가장 덜 중요한 숫자는 짝수가 되도록 숫자를 위쪽 또는 아래쪽 방향으로 근사한다. 예를 들어 $1.50과 $2.50 모두 $2가 된다.
    • 위쪽 또는 오른쪽으로만 근사를 하게 되면 평균값보다 약간 크거나 적은 값을 갖게 되기 때문에 이러한 방법을 사용한다.
    • 이 방법은 정수로 근사하지 않을 때에도, 이진수 비율 숫자들에도 적용될 수 있다.
  • Round-toward-zero (영방향근사): 양수 값을 아래쪽으로, 음수를 위쪽으로 근사
  • Round-down (하향 근사): 양수와 음수를 모두 아래쪽으로 근사
  • Round-up (상향근사): 양수와 음수를 위쪽으로 해서 근사

2.4.5 부동소수점 연산

IEEE 표준은 덧셈이나 곱셈 같은 산술연산의 결과를 결정하는 간단한 규칙을 명시하고 있다. 부동소수점 값 x, y를 실수로 보고, 일부 연산이 실수들에 대해 정의된다면 계산은 Round(x, y)가 되는데, 이것은 실수 연산의 정확한 결과 값을 근사한 것이다.

  • 부동 소수점 덧셈에서는 결합법칙이 성립하지 않는다.
  • 부동 소수점 곱셈은 교환법칙이 성립하며 결합법칙은 성립하지 않는다.
  • 부동 소수점 곱셈은 덧셈에 대해 분배법칙이 성립하지 않는다.

2.4.6 C에서 부동소수점

모든 C버전에서는 두가지의 부동소수점 자료형인 floatdouble을 제공한다. 이 자료형들은 단일 및 이중정밀도 부동소수점에 대응된다. 그리고 짝수 근사모드를 사용한다.
int, float, double 형식들간의 캐스팅을 할 때 프로그램은 숫자 값과 비트 표시를 다음과 같이 변경한다.

  • int -> float: 숫자는 오버플로우 할 수 없지만 근사될 수 있다.
  • int or float -> double: 넓은 범위와 보다 큰 정밀도로 인해 정확한 수치 값은 보존될 수 있다.
  • double -> float: 범위가 더 작아지기 때문에 값이 오버플로우 하여 양의 무한대 혹은 음의 무한대가 될 수 있다. 그 이외의 경우에도 정밀도가 더 작기 때문에 근사될 수 있다.
  • float or double -> int: 0방향으로 근사된다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/03   »
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 31
글 보관함