Introduction

Park Choong Ho·2021년 8월 20일
0

Introduction

현대 컴퓨터들은 두 값을 가지는 신호로 정보를 저장하고 표현합니다. 이 binary digits 또는 bits라 불리는 신호들은 디지털 혁명의 근간을 형성하고 있습니다. 인도로부터 시작해 수천년 동안 사용되어온 10진법은 인간에게 친숙한 표현법입니다. 인간은 손가락이 10개이기에 이는 당연한 수순입니다. 하지만, 이보다는 binary 값들이 기계에 더 적합합니다. 이진 신호를 통해 계산을 실행하는 전기 회로 구성은 굉장히 간단하고 신뢰할 수 있으며, 수천 수백만 전기회로를 연결하여 간단한 실리콘 칩을 생산하는 것도 가능합니다.

비트 하나는 그다지 유용하지 않습니다. 하지만, 여러 개 비트를 묶는다면 가능한 비트 패턴에 의미를 부여하여 무한한 집합 명령 패턴을 만들 수 있습니다. 예를 들어 이진법 시스템을 활용하여 음수가 아닌 숫자들을 인코딩하는데 활용할 수 있습니다. 기준 문자 코드를 통해 문서상 숫자와 심볼들을 인코딩하는 것도 가능합니다. 이 장에서는 이러한 인코딩들을 모두 확인해볼 것이고 동시에 실수와 음수를 표현하는 인코딩까지 살펴봅니다.

또한, 숫자를 표현하는데 있어 가장 중요한 3가지를 만나볼 것입니다. Unsigned 인코딩은 0보다 같거나 큰 숫자를 표현하는데 사용되며, 전통적 이진법 개념에 기초하고 있습니다. Two's-complment 인코딩은 signed정수(양수 음수 모두를 표현할 수 있는)를 표현하는 가장 일반적인 방식입니다. Floating-point 인코딩은 실수를 표현하는 과학적인 base-2 버전입니다. 컴퓨터는 정수와 실수를 계산하는데 있어 더하기 곱하기 같은 수학적 연산을 활용합니다.

컴퓨터는 숫자를 인코딩하는데 제한된 개수만큼 비트들을 사용하기에 어떤 연산들은 overflow(숫자가 너무 커서 표현할 수 없는 경우)할 수도 있습니다. Overflow는 예상치 못한 결과를 가져옵니다. 예를 들어, 오늘날 32-bit 컴퓨터들은 200 * 300 * 400 * 500을 계산하면 -884,901,888 이라는 결과를 내놓습니다. 이것은 일반적인 정수 연산에 반하는 결과입니다.

반면에, 컴퓨터 정수 연산은 여러 정수 연산 특징들을 만족합니다. 예를 들어, 곱셈 결합법칙과 교환법칙을 활용할 수 있습니다. 따라서 아래 모든 식들은 모두 -884,901,888이라는 결과를 낳습니다.

(500 * 400) * (300 * 200)
((500 * 400) * 300) * 200
400 * (200 * (300 * 500))

틀린 답이지만, 적어도 컴퓨터가 일정한 결과를 내놓는다는 것을 확인할 수 있습니다.

Floating-point 산수는 다른 수학적 특징들을 가지고 있습니다. 비록 오버플로우가 특별한 +∞ 값을 양산한다고 하더라도 floating-point에서 양수는 항상 양수입니다. Floating-point 계산은 한정적인 precision 표현으로 인해 결합법칙이 성립하지 않습니다. 예를 들어, C에서 (3.14+1e20)-1e20 은 대부분 컴퓨터에서 0.0 됩니다. 반면에 3.14+(1e20- 1e20)는 3.14가 됩니다. 정수와 실수 계산의 차이점은 각각 표현 방식의 한계를 어떻게 다루는지에 대한 차이입니다. 정수 표현은 상대적으로 더 적은 수를 정확하게 인코딩할 수 있는 반면, 실수 표현은 더 넓은 범위를 대략적으로만 표현 가능합니다.

실제 숫자 표현을 공부함으로써 값의 범위가 서로 다른 산수식에서 어떻게 표현되는지 이해할 수 있습니다. 이러한 이해는 큰 범위의 숫자 값을 정확하게 다루는 동시에 여러가지 기계, 운영체제, 컴파일러에 호환되는 프로그램을 만드는데 있어 중요한 역할을 합니다. 나중에 살펴보겠지만, 많은 컴퓨터 보안 취약성은 이러한 컴퓨터 계산의 미묘한 차이에 기인합니다. 초창기에는 프로그램 버그가 단순히 사람들을 불편하게 했을 뿐이지만, 오늘날에는 다른 사람의 시스템에서 허가되지 않은 권한을 얻기 위한 버그를 활용하는 해커들이 많이 있습니다. 이러한 부분은 프로그래머들이 자신의 프로그램이 어떻게 동작하고 어떻게 원치않은 방향으로 동작할 수 있는지를 이해하는 것을 더욱더 중요하게 합니다.

컴퓨터는 여러 숫자 값을 인코딩하기 위한 여러가지 이진 표현법을 사용합니다. 3장에서는 machine-level 프로그래밍을 통해 이러한 표현법과 더 가까워집니다. 이 장에서는 그러한 인코딩들을 살펴보고 숫자 표현을 어떻게 유추해내는지를 확인합니다.

또한, 직접적으로 비트레벨로 표현된 숫자들을 조작함으로써 여러 계산 동작들을 살펴볼 것입니다. 이러한 기술들을 이해하는 것은 숫자 표현식 성능을 최적화하는 컴파일러가 생성한 machine-level 코드를 이해하는데 있어 중요합니다.

이번 장은 수학적 원리에 기초해 있습니다. 기초적인 인코딩 정의에서부터 출발해 표현가능한 숫자 범위, 이러한 숫자들을 나타내는 비트 표현 방식 그리고 계산 특징까지 살펴볼 것입니다. 이러한 시각에서 이번 장을 공부하는 것은 중요합니다. 왜냐하면 프로그래머는 정수 실수 계산과 컴퓨터간 연관성을 이해하고 있어야 되기 때문입니다.

C++은 C에 기반합니다. 특히 같은 숫자 표현과 동작 방식을 활용합니다. 이번 장에서 말하는 C언어와 관련된 것들은 C++ 그대로 적용할 수 있습니다. 반면, 자바는 다소 다른 숫자 표현과 동작방식을 가지고 있습니다. C 표준이 좀 더 보편적인 활용을 위한 거라면, 자바 표준은 특정 포맷과 인코딩에 초점이 맞춰져 있습니다. 이번 장 몇몇 곳에서 이러한 자바 특징들을 살펴보도록 하겠습니다.

Aside: How to read this chapter

이번장에서는 숫자 그리고 다른 형태의 데이터들이 컴퓨터 상에서 어떻게 표현되는지 살펴볼 것입니다. 그리고 숫자 계산이 어떻게 동작하는지도 살펴봅니다. 따라서 이번 장은 수학을 다소 요구합니다. 종종 공식, 방정식 등을 쓸 수도 있습니다.

이러한 구성으로 인해, 수학 개념 원리를 초반부에 나오게끔 배치했습니다. 그리고 그 원리를 예시와 설명으로 이해할 수 있게끔 만들어 두었습니다. 원리들을 반복하며 살펴볼것을 권장드립니다. 예시와 설명들도 완전한 이해와 통찰을 얻을 때까지 지속하시기를 바랍니다. 여기에, 다소 복잡한 개념들에는 derivation을 제공합니다. Derivation은 수학적 증명과 비슷한 것이라 이해하면 됩니다. Derivation들을 이해하는 것을 목표로 삼아야 하겠지만, 처음에는 그냥 넘어가셔도 무방합니다.

이번 장에서, practice problem도 풀어보기 바랍니다. Practice problem은 능동적인 참여 가능하게 하고 여러분의 생각을 실행으로 옮기는데 도움을 줄 것입니다. 또한, 책을 좀더 쉽게 읽고 derivation도 따라가기 다소 수월해질 겁니다. 이번 장을 이해하는데 있어 필요한 수학 난이도는 고등학교 수학 정도이니 너무 겁먹을 필요는 없습니다.

profile
백엔드 개발자 디디라고합니다.

0개의 댓글