Proven C BookEnglish GitHub

4 단순한 기계 모델 — C의 탄생

먼저 알아야 할 것

1장 배경설명 · C가 왜 아직 쓰이는가
2장 기억의 구역들 · 기억의 구역 배치

돌아보기

1장에서 C가 운영체제와 임베디드 기기, 인터넷 기반시설 속에 지금도 살아 있다고 했다. 반세기가 넘은 언어가 어떻게 아직 그 자리에 있는가?

답. C가 서 있는 자리가 특별하기 때문이다. 그 자리는 기계와 사람이 만나는 가장 낮은 층이고, 기계는 반세기 동안 빨라졌을 뿐 일하는 방식의 뼈대는 놀랄 만큼 그대로다. 그 뼈대를 이 장에서 직접 들여다본다. 뼈대가 그대로인 한, 뼈대의 언어도 그대로 남는다.

이 장의 필요성과 맥락

2부는 「C 가 왜 그렇게 생겼는가」에 답하는 부이고, 그 답은 하드웨어에 있다. 그래서 가장 단순한 기계 그림부터 그린다. 이 그림은 뒤에서 두 번 수리된다 — 11장이 기억을 사다리로 고치고, 13장이 컴파일러를 편집자로 고친다. 일부러 틀린 그림을 먼저 주고 차차 수리하는 것이 이 부의 방식이라, 그 출발점이 여기다.

이 장이 끝나면

컴퓨터를 세 가지 부품 — 계산하는 곳, 기억하는 곳, 박자를 맞추는 것 — 의 단순한 그림으로 그릴 수 있게 된다. 정보의 최소 단위인 비트가 무엇인지, 왜 하필 2진법인지 알게 된다. 그리고 그 단순한 기계의 시절에 C라는 언어가 어떻게 태어났는지 보게 된다.

이 장에서 답할 질문

  1. “1초에 40억 번” 같은 광고 문구의 기가헤르츠(GHz)가 이 클록인가?
  2. 겨우 “가져와서 그대로 한다”의 반복으로 게임과 동영상과 인공지능이 어떻게 가능한가?
  3. 왜 하필 두 상태인가? 스위치 하나에 0부터 9까지 열 가지 상태를 담으면 훨씬 효율적이지 않은가?
  4. 바이트는 왜 하필 여덟 개 묶음인가? 처음부터, 그리고 어디서나 여덟 개였는가?
  5. 256가지밖에 안 되는 바이트로 어떻게 큰 수를 다루는가?
  6. 50년 전 기계에 맞춘 언어를 지금 배우는 것이 손해는 아닌가?

4.1 컴퓨터를 세 부품으로 그리기

컴퓨터는 복잡한 물건이다. 그러나 복잡한 것을 이해하는 첫걸음은 언제나 과감하게 단순한 그림을 그리는 것이다. 지금부터 컴퓨터를 딱 세 부품으로 그린다.

첫째, CPU. 계산하는 곳이다. 더하고, 비교하고, 다음에 무엇을 할지 정한다.

둘째, 메모리. 기억하는 곳이다. 계산에 쓸 재료와 계산의 결과가 여기에 놓인다.

셋째, 클록. 박자를 맞추는 것이다. 메트로놈처럼 일정한 간격으로 똑딱이고, CPU는 그 박자에 맞춰 한 걸음씩 일한다.

이 그림에서 컴퓨터가 하는 일은 이것이 전부다: 클록이 똑딱일 때마다, CPU가 메모리에서 다음 할 일을 하나 가져와서, 그대로 한다. 이것을 끝없이 반복한다.

문. “1초에 40억 번” 같은 광고 문구의 기가헤르츠(GHz)가 이 클록인가?

답. 그렇다. 4GHz는 메트로놈이 1초에 40억 번 똑딱인다는 뜻이다. 박자마다 CPU가 일을 한 걸음씩 진행하니, 박자가 빠를수록 같은 시간에 더 많은 걸음을 걷는다. 다만 걸음 수가 전부는 아니라는 것을 12장에서 보게 된다 — 한 걸음에 여러 일을 하는 요령이 현대 CPU의 진짜 무기다.

문. 겨우 “가져와서 그대로 한다”의 반복으로 게임과 동영상과 인공지능이 어떻게 가능한가?

답. 벽돌 한 장은 단순하지만 벽돌로 성을 쌓을 수 있는 것과 같다. 단순한 걸음이라도 1초에 수십억 번이면, 그리고 그 걸음들을 겹겹이 조직하면 — 작은 일들이 모여 함수가 되고, 함수가 모여 프로그램이 되고, 프로그램이 모여 운영체제가 되면 — 어떤 복잡한 일이든 지을 수 있다. 이 “겹겹이 쌓기”가 전산학의 심장인 추상화이고, 이 책 전체가 그 층계를 오르는 이야기다.

CPU가 “다음 할 일”로 가져오는 것을 명령이라 부른다. 명령은 대단한 것이 아니다. “이 수와 저 수를 더해라”, “이 값을 저 칸에 넣어라”, “방금 결과가 0이면 다른 곳으로 건너뛰어라” — 이 정도 수준의, 지독하게 단순한 지시다. 프로그램이란 이런 명령을 순서대로 늘어놓은 목록이고, 프로그래밍이란 그 목록을 사람이 감당할 수 있는 방식으로 적는 일이다.

4.2 비트 — 정보의 최소 단위

메모리가 “기억하는 곳”이라 했다. 그러면 무엇을, 어떤 모양으로 기억하는가.

전자 회로가 가장 잘하는 일은 두 가지 상태를 구별하는 것이다. 전압이 높거나, 낮거나. 스위치가 켜져 있거나, 꺼져 있거나. 이 둘 중 하나를 담는 가장 작은 기억 단위를 비트(bit)라 부른다. 우리는 두 상태에 0과 1이라는 이름을 붙인다.

흔한 오해. “컴퓨터 안 어딘가에 0과 1이 글자처럼 적혀 있다”

그럴듯한 생각이다 — 책과 화면마다 컴퓨터는 0과 1로 가득하다고 그려지니까. 그러나 기계 안에 숫자 글자가 있는 것이 아니다. 실제로 있는 것은 높거나 낮은 전압, 차 있거나 빈 전하 같은 물리 상태뿐이다. 0과 1은 그 물리 상태를 사람이 읽기 위해 붙인 이름, 즉 해석이다. 이 구별은 한가한 트집이 아니다 — “기억된 것 자체”와 “그것을 어떻게 읽을 것인가”의 분리는 이 책에서 계속 되돌아올 주제이고, 나중에 같은 비트 열을 수로도 글자로도 읽게 되는 이유다(8장, 9장).

문. 왜 하필 두 상태인가? 스위치 하나에 0부터 9까지 열 가지 상태를 담으면 훨씬 효율적이지 않은가?

답. 실제로 초기에는 10진 컴퓨터가 만들어지기도 했다. 그러나 열 단계의 전압을 구별하려면 단계 사이 간격이 좁아지고, 간격이 좁으면 잡음이나 온도 변화에 이웃 단계로 넘어가 버린다 — 즉 틀리기 쉽다. 두 상태는 간격이 가장 넓어서, 회로가 싸고 빠르고 잡음에 강하다. 2진법은 수학적 우아함 때문이 아니라 공학적 정직함 때문에 이겼다.

4.2.1 그런데 수학은 3을 가리킨다

방금 “수학적 우아함 때문이 아니라”고 했는데, 이 말은 생각보다 무겁다. ★ 수학만 따지면 2진법은 최적이 아니다. 최적은 3진법이다.

수학. 기수의 경제성

어떤 수 𝑁 을 기수 𝑏 로 적으려면 자릿수가 log𝑏𝑁 개 필요하다. 그리고 자리 하나가 𝑏 가지를 구별해야 하니, 그 자리를 만드는 비용을 𝑏 에 비례한다고 놓자. 그러면 전체 비용은

𝐸(𝑏,𝑁)=𝑏log𝑏𝑁=𝑏ln𝑏ln𝑁

이다. ln𝑁𝑏 와 무관하므로, 비용을 정하는 것은 𝑏/ln𝑏 하나다. 이것을 미분하면 (ln𝑏1)/(ln𝑏)2=0, 곧 ln𝑏=1 에서 최소가 된다.

𝑏=𝑒2.718

기수는 자연수여야 하므로 𝑒 에 가장 가까운 자연수 셋을 견주면 이렇다.

기수 𝑏𝑏/ln𝑏
22.8854
32.7307 — 최소
42.8854
104.3429

표 4.1

★ 두 가지가 눈에 띈다. 첫째, 2와 4가 정확히 같다4=22 이라 4/ln4=4/(2ln2)=2/ln2 이기 때문이다. 둘째, 3이 2보다 나은 정도는 겨우 5.7% 다.

계산해 보면 이 5.7% 마저 늘 나타나지는 않는다. 자릿수는 올림해야 하므로 작은 수에서는 뒤집히기도 한다.

표현할 수2진법3진법이긴 쪽
10310자리 × 2 = 207자리 × 3 = 212진법
10620자리 × 2 = 4013자리 × 3 = 393진법
10930자리 × 2 = 6019자리 × 3 = 573진법

표 4.2

4.2.2 실제로 만들어진 3진 컴퓨터 — Setun

이것이 탁상공론만은 아니었다. 1958년 모스크바 대학에서 Setun(세툰)이라는 3진 컴퓨터가 실제로 만들어졌고, 1959년부터 1965년까지 50대가 생산되어 그중 30대가 대학과 단과대학에 설치되었다.1

실제 사례. Setun — 3진법이 실제로 이겼던 잠깐

세르게이 소볼레프가 1956년에 설계를 시작했고 니콜라이 브루센초프가 이끌었다. 이름은 대학 근처를 흐르는 강에서 따왔다. 1958년 12월에 시제품이 나왔다.

왜 그때는 3진법이 유리했는가가 핵심이다. 이 기계는 트랜지스터가 아니라 페라이트 자심(ferrite core)과 다이오드로 논리를 만들었다. 자심은 자화 방향이 두 가지이므로, 「음의 자화 / 자화 없음 / 양의 자화」라는 세 상태를 자연스럽게 갖는다. 그러니까 3진법을 억지로 흉내 낸 것이 아니라, 부품이 원래 그렇게 생겼던 것이다. 박물관 기록은 그 결과를 이렇게 적는다 — 같은 성능의 2진 기계보다 “속도와 신뢰성이 낫고, 장비와 전력이 덜 든다”.

숫자 표현은 균형 3진법(balanced ternary)이었다. 자릿값이 0, 1, 2 가 아니라 –1, 0, +1 이다. 여섯 자리(트릿)를 묶어 한 「트라이트」로 삼았는데, 2진법으로 치면 약 9.5비트다.

끝은 기술이 아니라 행정이었다. 수요가 있었는데도 연 10~15대만 만들다가 1965년에 중단됐다. 박물관의 기록은 담담하다 — 소련의 컴퓨터 생산 당국이 이 “계획에 없던, 대학의 별난 상상의 산물”을 곱게 보지 않았고, 같은 성능에 2.5배 넘게 비싼 2진 기계로 대체되었다. 1970년에 후속작 Setun-70 이 나왔지만 양산에는 이르지 못했다.

균형 3진법 자체는 지금도 아름다운 물건이다. 크누스는 이것을 두고 “아마도 모든 수 체계 중 가장 예쁜 것” 이라고 적었다.2 예쁜 이유가 몇 가지 있다.

4.2.3 그러면 왜 2진법이 이겼는가

수학이 3을 가리키고 실물도 만들어졌는데 세상은 2진법이다. 이유는 비용 모형이 틀렸기 때문이다.

위 계산은 “자리 하나의 비용이 𝑏 에 비례한다”고 놓았다. 이것은 𝑏 가지 상태마다 부품이 하나씩 필요한 장치 — 이를테면 𝑏 갈래 스위치 — 를 모형화한 것이다. 페라이트 자심이 거기에 가까웠다. 그러나 트랜지스터 회로의 비용을 정하는 것은 부품 수가 아니라 전압 준위를 얼마나 확실히 구별하는가다.

기수이웃 준위 사이 간격무엇을 뜻하나
2전원 전압의 100%완전히 켜거나 완전히 끈다
350%중간 준위를 정확히 붙들고 있어야 한다
433%
1011%

표 4.3

★ 간격은 1/(𝑏1) 로 줄어든다. 그리고 이 간격이 곧 잡음 여유다. 2진법은 트랜지스터를 포화 영역에서 쓴다 — 완전히 켜거나 완전히 끄므로 중간에 머무는 시간이 거의 없고, 전원 전압만큼의 여유를 통째로 갖는다. 3진법은 중간 준위를 아날로그적으로 붙들어야 하니 여유가 절반으로 줄고, 소자마다 다른 제조 편차가 그 절반을 갉아먹는다.

그래서 정리하면 이렇다.

무엇을 세느냐
자릿수 × 기수 (부품 수)3진법 — 다만 2진법보다 5.7%
잡음 여유 · 속도 · 제조 편차★ 2진법 — 압도적으로

표 4.4

그리고 5.7% 는 그 대가를 치를 만한 값이 아니었다. 2진법에 딸려 온 것들 — 부울 대수라는 성숙한 이론, 오류 정정 부호, 통신 규약, 반세기치 설계 자산 — 까지 세면 격차는 훨씬 벌어진다.

흔한 오해. “3진법이 수학적으로 최적이니 언젠가 3진 컴퓨터로 바뀔 것이다”

“수학적으로 최적”이라는 말이 성립하는 것은 특정 비용 모형 아래에서다. 그 모형이 오늘의 반도체에는 맞지 않는다. 최적화 문제는 목적 함수를 바꾸면 답이 바뀌는데, 여기서는 목적 함수 쪽이 틀렸던 것이다.

★ 다만 연구가 죽은 것은 아니다. 탄소 나노튜브 트랜지스터(CNTFET)처럼 문턱 전압을 소자마다 다르게 만들 수 있는 소자에서는 3진 논리가 다시 검토되고 있고, 2024년에는 세 상태를 안정적으로 오가는 소자를 만들었다는 보고도 나왔다.3 노리는 것은 자릿수 절약이 아니라 배선과 전력이다 — 한 선으로 더 많은 정보를 보내면 칩에서 가장 비싼 자원인 배선이 줄어든다.

그러니 정확한 서술은 이렇다 — 비용 모형이 바뀌면 답이 바뀔 수 있다. 오늘의 CMOS 에서는 2진법이 옳고, 다른 소자에서는 다시 물어야 한다.

★ 이 이야기를 굳이 길게 한 이유가 있다. 이 책에서 되풀이해 만날 무늬이기 때문이다 — 깔끔한 이론이 가리키는 답과 물건을 만들 때의 답이 다르다. C 의 여러 결정도 그렇게 생겼다. 이론적으로 더 나은 선택지가 있었는데도 그때의 기계가 그것을 감당하지 못했거나, 이미 쌓인 코드가 그것을 막았다. 2진법은 그 무늬의 가장 오래되고 가장 성공한 사례다.

비트 하나는 두 가지를 구별한다. 비트를 여러 개 묶으면 구별할 수 있는 가짓수가 곱으로 불어난다. 두 개면 네 가지(00, 01, 10, 11), 세 개면 여덟 가지다. 여덟 개를 묶은 것에는 바이트(byte)라는 이름이 붙어 있고, 한 바이트는 256가지를 구별한다.

문. 바이트는 왜 하필 여덟 개 묶음인가? 처음부터, 그리고 어디서나 여덟 개였는가?

답. 아니다 — 바이트의 크기는 8비트로 고정된 적이 없다. 원래 “바이트”는 문자 하나를 담는 묶음이라는 뜻으로 쓰인 말이고, 그 크기는 기계마다 달랐다. 초기 컴퓨터들에는 6비트, 7비트, 9비트 바이트가 실제로 있었고, 워드가 36비트라서 바이트를 6비트씩 여섯 개로 자르던 기계도 있었다. 8비트가 대세가 된 것은 1960년대 IBM의 대형 컴퓨터(System/360)가 8비트를 채택하고 산업이 그 뒤를 따르면서다. 그래서 정확함이 생명인 통신 규격들은 지금도 “바이트” 대신 옥텟(octet, 정확히 8비트)이라는 말을 쓴다 — 바이트라는 말만으로는 크기가 보장되지 않았던 역사의 흔적이다.

그리고 이것은 옛날이야기만이 아니다. 지금도 일부 신호 처리용 프로세서(DSP)는 가장 작은 기억 단위가 16비트나 32비트라서, 그 위의 C에서는 바이트가 16비트·32비트다. 흔히 만나는 기계에서는 사실상 전부 8비트지만, “바이트 = 무조건 8비트”는 약속이 아니라 관행이다.

C 표준(C23)의 정의도 그래서 신중하다. C23에서 바이트란 “기본 문자 하나를 담을 수 있는, 주소를 붙일 수 있는 가장 작은 기억 단위”이고, 그 비트 수는 CHAR_BIT라는 이름으로 공개하되 8 이상이라고만 못박는다 — 정확히 8이 아니라 “최소 8”이다. 이 책은 이후 흔한 기계들을 따라 바이트 = 8비트로 놓고 진행하되, 그것이 표준의 보장이 아니라 사실상의 관행임을 여기 적어 둔다. (표준 위원회는 차기 표준에서 8비트로 아예 못박는 방향을 논의하고 있다 — 관행이 반세기를 버티면 약속으로 승격되는 셈이다.)

수학. 묶음의 크기와 가짓수

비트 𝑛개의 묶음이 구별할 수 있는 상태의 가짓수는, 각 자리가 독립적으로 두 값을 가지므로

2×2××2=2𝑛

이다. 28=256, 216=65536, 2324.3×109. 이 책에서 2𝑛은 계속 나타난다 — 기억의 크기, 표현 가능한 수의 범위, 주소의 개수가 전부 이 꼴이다.

묶음으로 를 나타내는 방법은 우리가 쓰는 십진법과 같은 원리인 위치 기수법이다. 십진수 304=3102+0101+4100 이듯, 2진수 1012=122+021+120=5 다. 자리 하나가 10 대신 2의 거듭제곱을 짊어질 뿐이다.

문. 256가지밖에 안 되는 바이트로 어떻게 큰 수를 다루는가?

답. 십진법에서 한 자리로 부족하면 자리를 늘리듯, 바이트도 여러 개를 이어 붙여 큰 수를 담는다. 몇 개를 이어 붙이는 것이 자연스러운가는 기계마다 정해져 있다 — 그 “자연스러운 묶음”이 다음 장의 주인공인 워드다.

4.3 그 단순한 기계의 시절, C가 태어났다

지금까지 그린 세 부품의 그림은 오늘의 컴퓨터에게는 지나치게 단순한 그림이다(그 이야기가 9·12장이다). 그런데 1970년대 초의 컴퓨터에게는 이 그림이 거의 사실 그대로였다. 클록은 초당 수십만 번 수준이었고, CPU는 정말로 한 박자에 한 걸음씩 걸었고, 메모리는 정말로 한 줄로 늘어선 사물함이었다.

C는 바로 그 시절, 그 단순한 기계 위에서 태어났다 — 그런데 무(無)에서 솟은 것이 아니라, 짧고 뚜렷한 족보의 끝에서 태어났다. 그 족보를 알면 C의 생김새 몇 가지가 단번에 설명되므로, 여기 간추려 둔다.

출발점은 1960년대 영국의 CPL이라는 야심찬 언어였다 — 너무 야심차서 당대 기계로는 완성이 어려웠고, 케임브리지의 마틴 리처즈가 그 정수만 추려 BCPL(1967)이라는 작고 실용적인 언어를 만들었다. BCPL의 급진적 단순함은 이것이다: 타입이 하나뿐이다. 모든 값은 그냥 워드 한 칸이고, 그것을 수로 쓸지 주소로 쓸지는 연산이 정한다. 다음 장에서 볼 “칸에 든 것은 그저 비트이고 해석이 정한다”를 언어 전체로 밀어붙인 셈이다.

벨 연구소의 켄 톰프슨은 낡은 PDP-7 위에서 초기 Unix를 만들며, BCPL을 자기 취향으로 더 줄인 B(1969년경)를 만들었다 — 여전히 타입은 하나였고, 오늘까지 살아남은 간결한 어법들(++ 같은)이 이 손질에서 왔다. 그런데 연구소가 새 기계 PDP-11을 들이자 B의 전제가 깨졌다. PDP-11의 메모리는 워드가 아니라 바이트 단위로 주소가 붙었고(5장의 복도가 바로 이 모습이다), 크기가 다른 데이터 — 1바이트짜리 문자, 2바이트짜리 정수, 그리고 부동소수점 — 를 구별해 다뤄야 했다. “모든 것이 워드 한 칸”인 B로는 이 기계를 제대로 부릴 수 없었던 것이다.

그래서 데니스 리치가 B에 타입을 들였다 — 문자와 정수를 구별하고, 무엇의 주소인지 아는 포인터를 만들고, 구조체를 보탰다. 이 개조가 1971–73년 사이에 쌓여 새 이름을 얻은 것이 C다. 즉 C의 타입 시스템은 철학적 설계가 아니라 바이트 주소 기계라는 현실에 대한 응답이었다. C가 뼛속까지 바이트 지향인 것(4장의 바이트, 5장의 복도), 포인터가 언어의 한복판에 있는 것, 그러면서도 타입이 헐거운 편인 것(타입 하나 짜리 조상의 유산) — 전부 이 족보의 흔적이다.

덧붙여 두 가지. 오늘의 눈에 익숙한 어법이 처음부터 있었던 것은 아니다 — 이를테면 지금의 +=는 초기 C에서 =+라고 적었고, 몇 해 뒤에야 지금 꼴이 됐다(헷갈림 때문이었다: x=-1이 “빼기”인지 “대입”인지). 언어는 이렇게 실사용의 상처를 먹으며 다듬어진다. 그리고 이 시절의 C에는 아직 표준도, 규격서도 없었다 — 언어의 정의는 사실상 “리치의 컴파일러가 받아 주는 것”이었다. 이 헐거움이 어떤 소동으로 자라 표준(C89)을 부르게 되는지는 12장에서 잇는다.

그래서 초기의 C는 과장을 조금 보태면 그 시절 기계의 정직한 별명이었다. C의 연산 하나가 기계 명령 한두 개에 그대로 대응했고, 프로그래머는 C를 쓰면서도 기계가 무엇을 할지 훤히 내다볼 수 있었다. C가 “기계에 가까운 언어”라는 평판은 여기서 왔다 — 그리고 이 평판이 오늘날 절반만 맞는 말이 된 사연이 이 부의 뒷장들(11–14장)이다.

실제 사례. 이식성 혁명 — Unix를 C로 다시 쓰다

1973년경 Unix의 심장부가 어셈블리에서 C로 다시 쓰였다. 당시로서는 파격이었다 — 운영체제는 기계어 수준에서 짜야 한다는 것이 상식이었기 때문이다. 효과는 압도적이었다. 어셈블리 Unix는 PDP-11에 묶여 있었지만, C로 쓰인 Unix는 “C 컴파일러만 있으면” 다른 기계로 옮길 수 있었다. 운영체제가 특정 기계의 소유물이 아니게 된 것이다. 오늘날 Linux, Windows, macOS의 커널이 모두 C(또는 그 후예)로 쓰여 있고, 새 프로세서가 나오면 가장 먼저 C 컴파일러부터 이식되는 전통이 여기서 시작됐다.

문. 50년 전 기계에 맞춘 언어를 지금 배우는 것이 손해는 아닌가?

답. 거꾸로다. 기계의 뼈대 — 메모리, 주소, 바이트, 명령의 순차 실행 — 는 50년 동안 바뀌지 않았고, C는 그 뼈대를 가장 얇게 감싼 언어로 남아 있다. 그래서 C를 배우는 일은 특정 언어의 문법 암기가 아니라 컴퓨터 그 자체를 배우는 일에 가깝다. 이후에 어떤 언어를 쓰게 되든, 그 언어의 밑바닥에는 거의 언제나 C가 깔려 있다.

이 장의 그림을 정리하면 이렇다. 기계는 클록의 박자에 맞춰 메모리에서 명령을 가져와 그대로 실행하는 일을 반복하고, 기억은 두 상태의 최소 단위인 비트로 이루어진다. C는 이 그림이 거의 사실이던 시절에, 이 그림을 언어로 옮겨 태어났다.

다음 장은 세 부품 중 메모리를 자세히 들여다본다. 사물함 복도를 걸으며 칸마다 붙은 번호 — 주소 — 를 읽고, 기계가 한 번에 집는 자연스러운 묶음 — 워드 — 을 재고, 여러 바이트짜리 수를 사물함에 넣는 두 가지 순서 — 엔디안 — 를 구경한다. C의 포인터라는 유명한 개념이 바로 이 복도에서 태어났다.

  1. Development of ternary computers at Moscow State University. Russian Virtual Computer Museum. computer-museum.ru/english/setun.htm
  2. Donald E. Knuth. 1997. The Art of Computer Programming, Volume 2: Seminumerical Algorithms (3rd ed.). Addison-Wesley, Reading, MA. §4.1.
  3. Science Advances 게재 연구. science.org/doi/10.1126/sciadv.adt1909 — 다만 논문 수준의 성과이고 제품이 된 것은 아니다.