분자에서 근호가 사라지면서 x 가 나타났고, 그것이 분모의 x 와 지워졌습니다. 남은 식은 x=0 에서도 뜻이 있어 값이 21 입니다. 문제가 되던 자리가 조작 하나로 없어졌습니다. 이 손놀림은 28번 · 극한에서 그대로 다시 씁니다.
자릿수 손실
x+1−x 를 x=100000000 에서 계산해 봅니다. 두 근호값이 소수점 아래까지 거의 같은 큰 수라, 손으로 여덟 자리까지만 적어 두고 빼면 앞자리가 전부 지워지고 믿을 수 있는 자리가 하나도 안 남습니다.
같은 식을 켤레로 고쳐 봅니다. 분모가 1이라고 보고 위아래에 x+1+x 를 곱합니다.
x+1−x=x+1+x(x+1)−x=x+1+x1
이제 큰 수를 빼는 자리가 아예 없습니다. 분모가 대략 20000 이므로 값은 0.00005 쯤입니다. 같은 값을 두 모양으로 적을 수 있을 때, 큰 수끼리 빼는 모양은 피합니다. 뒤에서 어림값을 다룰 때 이 자리가 다시 나옵니다.
완전제곱
x2+8x+3 처럼 늘어놓은 이차식을 (x+p)2+q 꼴로 고치는 조작입니다.
한 변이 x 인 정사각형에 폭 4짜리 띠를 오른쪽과 아래에 하나씩 붙이면 x2+4x+4x=x2+8x 입니다. 그런데 오른쪽 아래 모서리 한 칸이 비어 있습니다. 그 칸이 4×4=16 입니다.
x2+8x+3=x2+8x+16−16+3=(x+4)2−13
16을 더했으니 그만큼 도로 뺐습니다. 값은 그대로이고 모양만 바뀌었습니다.
절차는 두 줄입니다. 가운데 항의 계수를 반으로 나눠 괄호 안에 넣고, 그 제곱을 뺍니다.
x2+bx=(x+2b)2−4b2
이렇게 고쳐 두면 공짜로 따라오는 것이 하나 있습니다. 제곱은 0 이상이므로 (x+4)2−13 은 −13 보다 작아질 수 없습니다. x=−4 에서 최솟값 −13 입니다. 늘어놓은 모양으로는 안 보이던 것이 보입니다.
상수항과 계수
상수항이 아예 없어도 절차가 달라지지 않습니다. 뺄 제곱만 그대로 뺍니다.
x2+5x=(x+25)2−425
계수가 홀수라 반으로 나눈 값이 분수가 되었을 뿐입니다. x=−25 에서 최솟값 −425 입니다.
x2 앞에 계수가 붙으면 먼저 묶어 냅니다.
3x2−12x+5=3(x2−4x)+5=3[(x−2)2−4]+5=3(x−2)2−7
괄호 밖으로 나올 때 묶어 낸 3이 다시 곱해진다는 것만 지키면 됩니다. 3×(−4)=−12 이고 −12+5=−7 입니다.
음수 계수와 최댓값
계수가 음수일 때가 부호를 가장 많이 틀리는 자리입니다. −1 을 묶어 내면 괄호 안의 부호가 전부 뒤집힙니다.
−x2+6x−5=−(x2−6x)−5=−[(x−3)2−9]−5=−(x−3)2+4
−x2+6x 에서 −1 을 빼내니 x2−6x 가 되었고, 대괄호를 풀 때 −9 가 +9 로 돌아와 9−5=4 가 남았습니다.
이번에는 최댓값이 읽힙니다. (x−3)2 이 0 이상이므로 −(x−3)2 은 0 이하이고, 전체는 4를 넘지 못합니다. x=3 에서 최댓값 4 입니다. 앞 계수의 부호가 최솟값과 최댓값을 가릅니다.
두 문자의 완전제곱
문자가 둘이어도 각각 따로 완전제곱을 만들면 됩니다. 서로 섞이지 않으니 두 번 하면 끝입니다.
x2+y2+2x−4y=(x2+2x)+(y2−4y)=[(x+1)2−1]+[(y−2)2−4]
=(x+1)2+(y−2)2−5
이 값이 0이 되는 자리를 찾으면 (x+1)2+(y−2)2=5 입니다. 두 제곱의 합이 일정한 이 모양이 점 (−1,2) 에서 거리가 5 인 점들의 자취 — 곧 원을 적는 식입니다. 24번 · 좌표평면과 직선에서 이 모양을 정면으로 다룹니다. 여기서는 늘어놓은 식을 완전제곱 둘로 고치는 순간 그 정체가 드러난다는 것까지만 봅니다.
치환과 되돌리기
같은 덩어리가 여러 번 나오면 문자 하나로 바꿔 식을 줄입니다.
(x2+1)2−5(x2+1)+6
x2+1 을 t 라 놓습니다.
t2−5t+6=(t−2)(t−3)
이제 t 를 도로 돌려놓습니다. 되돌리는 것을 잊는 것이 이 조작의 유일한 함정입니다.
(x2+1−2)(x2+1−3)=(x2−1)(x2−2)=(x+1)(x−1)(x2−2)
복이차식
x4−5x2+4 처럼 짝수 차수만 있는 사차식을 복이차식이라 합니다. t=x2 으로 놓으면 그대로 이차식이 됩니다.
t2−5t+4=(t−1)(t−4)
되돌리면 (x2−1)(x2−4) 이고, 둘 다 제곱의 차라 한 번 더 묶입니다.
(x+1)(x−1)(x+2)(x−2)
이 식이 0이 되는 x 는 ±1 과 ±2 로 넷입니다. 사차식을 그대로 놓고 근을 찾으려면 막막하지만, 치환 한 번으로 아는 모양이 되었습니다.
대칭식
x 와 x1 가 짝을 이뤄 나오는 식에서는 그 합을 통째로 문자 하나로 놓습니다. t=x+x1 라 두고 양변을 제곱합니다.
t2=x2+2⋅x⋅x1+x21=x2+x21+2
가운데 항이 2 로 딱 떨어지는 것이 이 치환이 되는 이유입니다. 옮기면 이렇게 됩니다.
x2+x21=t2−2
x+x1=3 이라면 x 를 구하지 않고도 x2+x21=9−2=7 입니다. 묻는 값이 덩어리로만 되어 있으면 x 자체는 끝까지 구하지 않아도 됩니다.
치환의 범위
치환에는 되돌리기 말고 함정이 하나 더 있습니다. t 가 아무 값이나 되는 것이 아닙니다.
x4−3x2−4=0
t=x2 으로 놓으면 t2−3t−4=0 이고 (t−4)(t+1)=0 이라 t=4 또는 t=−1 입니다. 그런데 t 는 x2 이므로 0보다 작을 수 없습니다.
t=x2⇒t≥0
t=−1 은 되돌릴 x 가 없으니 버립니다. t=4 에서 x=±2 만 답입니다. 문자를 바꿔 놓을 때는 그 문자가 다닐 수 있는 범위도 함께 적어 둡니다.t=x2+1 로 놓았다면 t≥1 이고, 그 범위 밖의 답은 같은 이유로 버립니다.
전개·묶기와 줄 복원
같은 식을 두 방향으로 고칠 수 있을 때 어느 쪽으로 갈지는 무엇을 하려는가가 정합니다.
하려는 일
가는 방향
값을 넣어 계산한다
전개
동류항을 합쳐 정리한다
전개
약분해서 지운다
묶기
0이 되는 자리를 찾는다
묶기
최솟값·최댓값을 읽는다
묶기(완전제곱)
x2−9=0 을 풀 때 전개할 것이 없으니 묶습니다. (x+3)(x−3)=0 이 되고, 곱이 0이면 둘 중 하나가 0이므로 x=3 또는 x=−3 입니다. 늘어놓은 채로는 이 결론이 안 나옵니다.
호너의 방법
표의 첫 줄에는 예외가 하나 있습니다. 값을 넣어 계산할 때도 묶어 두는 편이 곱셈이 적습니다.
x3+2x2+3x+4=((x+2)x+3)x+4
오른쪽은 안쪽 괄호부터 차례로 계산합니다. x=2 라면 (2+2)=4, 4×2=8, 8+3=11, 11×2=22, 22+4=26 입니다. 왼쪽으로 계산해도 8+8+6+4=26 으로 같습니다.
곱셈 횟수를 세어 봅니다. 계수를 일반으로 두고 ax3+bx2+cx+d 를 그대로 계산하면 a⋅x⋅x⋅x 에 곱이 셋, b⋅x⋅x 에 둘, c⋅x 에 하나로 모두 여섯 번입니다. 묶은 모양 ((ax+b)x+c)x+d 는 x 를 곱하는 세 번뿐입니다.
이렇게 안쪽부터 묶어 차례로 계산하는 방식을 호너의 방법 이라고 합니다. 차수가 높아질수록 차이가 벌어져서, n 차식이면 곱셈이 n 번으로 끝납니다.
유도 도중의 줄
표가 갈라 주지 못하는 자리도 있습니다. 유도의 한가운데에서는 무엇을 하려는지가 아직 안 정해져 있기 때문입니다.
x+1(x+1)(x+2)
지울 것이 보이니 묶은 채로 두는 것이 맞습니다. 그런데 이 줄이 더 긴 계산의 도중이고, 다음 줄에서 값을 대입할 예정이라면 전개해 두는 편이 나을 수도 있습니다. 한 줄만 보고 정할 수 없습니다.
이럴 때는 다음 줄에서 무엇을 할지 먼저 정하고 돌아옵니다. 정해지지 않았으면 묶은 모양으로 두는 편이 안전합니다. 묶은 것은 언제든 펼 수 있지만, 펴 놓은 것을 다시 묶으려면 찾기를 한 번 더 해야 하기 때문입니다.
조작의 이름
이 글의 본론입니다. 두 줄이 나란히 있고 사이가 비어 있을 때, 무엇이 달라졌는지부터 봅니다.
달라진 것
한 일
항의 수가 늘었다
전개했거나 통분했다
항의 수가 줄었다
묶었거나 약분했다
근호가 사라졌다
켤레를 곱했다
(□)2+□ 모양이 됐다
완전제곱을 만들었다
없던 문자가 생겼다
치환했다
양변에 같은 것이 붙었다
등식의 성질을 썼다
3번 글에서 자기 풀이의 각 줄에 무슨 조작을 했는지 이름을 붙이는 습관을 들였습니다. 여기서는 그 습관을 남이 쓴 유도에 적용합니다. 달라진 것을 보고 조작의 이름을 붙이면, 그 조작을 직접 해 보는 것으로 빈 줄이 채워집니다.
한 번 해 봅니다.
a−ba2−b2=a+b
항의 수가 줄었으니 묶었거나 약분했습니다. 분자를 묶어 보면 (a+b)(a−b) 이고, 분모와 같은 a−b 가 있으니 지운 것입니다. 빈 줄은 이렇습니다.
a−ba2−b2=a−b(a+b)(a−b)=a+b
a=b 라는 단서도 함께 복원됩니다.
두 걸음짜리 등호
건너뛴 걸음이 늘 하나인 것은 아닙니다. 이 글을 연 그 줄을 다시 봅니다.
5+31=25−3
여기에는 조작이 둘 들어 있습니다. 켤레를 위아래에 곱한 것과 분모 (5+3)(5−3) 을 계산해 2로 적은 것입니다. 그래서 복원하면 줄이 셋이 됩니다.
5+31=(5+3)(5−3)5−3=5−35−3=25−3
한 줄에 조작 하나가 되도록 펴는 것이 복원의 기준입니다. 조작 이름을 두 개 이상 붙여야 하는 줄이 있으면 아직 덜 편 것입니다.
대입 검산
붙인 이름이 틀릴 수도 있습니다. 그때 가르는 방법은 하나입니다. 양쪽에 같은 수를 넣어 값을 비교합니다.
xx2+2x=x+2
"약분했다"고 보고 x 를 지워 봤더니 x+2 가 나옵니다. x=2 를 넣으면 왼쪽은 28=4 이고 오른쪽도 4 라 맞습니다. 만약 분자를 x(x+2) 로 묶지 않고 x 만 지워 x2+2 라고 적었다면 x=2 에서 6 이 되어 어긋납니다. 한 번 대입해 보면 그 자리에서 갈립니다.
값이 맞았다고 조작 이름까지 맞은 것은 아니지만, 틀린 이름은 거의 언제나 값에서 걸립니다. 대입 한 번이 가장 싼 검사입니다.
복원의 기준
「쉽게 알 수 있듯이」로 넘어간 줄을 만나면 어디까지 파고들지 정해야 합니다. 기준은 이렇습니다.
그 줄에 무슨 조작을 했는지 이름을 붙여 말할 수 있으면 멈춥니다. "통분하고 약분했다"까지 말할 수 있으면 손으로 다시 적어 볼 필요가 없습니다. 이름이 안 붙으면 위의 표로 돌아가 달라진 것을 세고, 조작 하나짜리 줄이 될 때까지 펍니다.
모든 줄을 다 펴려고 하면 유도를 못 읽습니다. 목적은 남의 계산을 검사하는 것이 아니라 논지를 따라가는 것이고, 막히는 줄만 펴면 됩니다.
연습 문제
빈 줄을 채우는 연습이므로 머릿속으로 건너뛰지 말고 한 줄씩 적으세요.
연습 1 — 전개와 묶기
(a+b)3 을 전개하세요.
(a+b)2(a+b)=(a2+2ab+b2)(a+b) 를 전개하면 a3+3a2b+3ab2+b3.
1번의 결과를 다시 (a+b)3 으로 묶으세요. 무엇을 보고 알아봤는지도 적으세요.
첫 항이 a3, 끝 항이 b3, 가운데 두 항의 계수가 3과 3이고 문자가 a2b, ab2 로 한 칸씩 옮겨 갑니다. 이 모양이면 (a+b)3 입니다.
실수를 2^b개 격자에 사상할 때 오차의 분산이 왜 Δ²/12인지 유도하고, 그것이 비트당 6.02dB라는 SNR로 번역되는 과정을 실측과 대조했습니다. 이상치 하나가 나머지 값의 유효 비트를 어떻게 먹는지, 그리고 int4에서 성능이 무너지는 지점을 오차 예산으로 미리 계산하는 법까지.
최댓값 빼기, 로그 공간, log1p·expm1, 분산의 두 공식, 정규화의 ε, fp32 누산, 역행렬 대신 solve — 프레임워크가 몰래 해 주는 일곱 가지를 하나씩 꺼내 각각 어떤 고장을 막는지 직접 재 봤습니다. 수식을 그대로 옮긴 코드가 왜 라이브러리보다 나쁜지에 대한 목록입니다.
0.1 + 0.2가 0.3이 아닌 이유부터 시작해 머신 엡실론을 유도하고, 같은 16비트인데 fp16과 bf16이 서로 다른 지점에서 터지는 이유, 비슷한 수를 뺄 때 유효자리가 사라지는 파괴적 상쇄, 그리고 1,000만 개를 순서만 바꿔 더했을 때 오차가 백만 배 갈리는 실험까지 직접 재 봤습니다.