루아 레퍼런스 매뉴얼 — 표준 라이브러리: 테이블·수학

루아 레퍼런스 매뉴얼 — 표준 라이브러리: 테이블·수학

루아의 표준 라이브러리 중 **테이블 조작(table manipulation)**과 **수학 함수(mathematical functions)**를 다루는 섹션 6.6과 6.7을 옮겨왔어요. 테이블은 루아에서 사실상 유일한 자료 구조라서, 그걸 다루는 함수들은 정말 자주 쓰게 돼요. 수학 쪽은 삼각함수부터 난수까지, 이름 그대로 수치 계산에 필요한 기본기를 챙겨둔 라이브러리예요.

번역할 때 함수 시그니처와 코드, 숫자, 동작 조건은 원문 그대로 보존했어요. 설명은 강사가 옆에서 말해 주는 톤으로 다듬었죠.

출처: Lua 5.4 Reference Manual — §6.6 Table Manipulation, §6.7 Mathematical Functions (https://www.lua.org/manual/5.4/manual.html)

본문

6.6 – 테이블 조작 (Table Manipulation)

이 라이브러리는 테이블 조작을 위한 범용 함수들을 제공해요. 모든 함수가 table 테이블 안에 담겨 있어서 table.함수명 형태로 호출하게 됩니다.

기억해 둘 점이 하나 있어요. 어떤 연산이 테이블의 길이를 필요로 할 때는, 길이 연산자(#)에 대한 모든 주의사항이 그대로 적용돼요(§3.4.7 참조). 그리고 이 라이브러리의 모든 함수는 인자로 받은 테이블에서 숫자 키가 아닌 것들은 무시합니다.


table.concat (list [, sep [, i [, j]]])

모든 요소가 문자열 또는 숫자인 리스트가 주어졌을 때, list[i]..sep..list[i+1] ··· sep..list[j] 문자열을 반환해요.

sep의 기본값은 빈 문자열, i의 기본값은 1, j의 기본값은 #list예요. 만약 ij보다 크면 빈 문자열을 반환합니다.


table.insert (list, [pos,] value)

value를 리스트의 pos 위치에 삽입해요. 이때 list[pos], list[pos+1], ···, list[#list] 요소들이 뒤로 한 칸씩 밀려나요.

pos의 기본값은 #list + 1이라서, table.insert(t, x)라고 호출하면 그냥 t맨 끝에 x를 추가하게 됩니다.


table.move (a1, f, e, t [,a2])

테이블 a1에서 테이블 a2로 요소들을 옮겨요. 아래 다중 할당(multiple assignment)과 같은 일을 수행한다고 보면 돼요:

a2[t],··· = a1[f],···,a1[e]

a2의 기본값은 a1이에요. 목적지 범위는 출발지 범위와 겹쳐도 괜찮아요. 옮길 요소의 개수는 루아 정수(integer)에 담길 수 있는 크기여야 합니다.

반환값은 목적지 테이블 a2예요.


table.pack (···)

모든 인자를 키 1, 2, ...에 저장한 새 테이블을 만들고, 인자의 총 개수를 담은 "n" 필드도 함께 넣어 반환해요.

주의할 점은, 인자 중에 nil이 섞여 있으면 결과 테이블이 시퀀스(sequence)가 아닐 수 있다는 거예요.


table.remove (list [, pos])

리스트에서 pos 위치의 요소를 제거하고, 제거된 요소의 값을 반환해요.

pos가 1과 #list 사이의 정수라면 list[pos+1], list[pos+2], ···, list[#list] 요소들을 앞으로 한 칸씩 당기고, list[#list] 요소를 지워요. pos#list가 0일 때 0이거나, #list + 1일 수도 있습니다.

pos의 기본값은 #list예요. 그래서 table.remove(l)이라고 호출하면 리스트 l마지막 요소를 제거하게 돼요.


table.sort (list [, comp])

리스트 요소들을 list[1]부터 list[#list]까지 주어진 순서에 따라 제자리에서(in-place) 정렬해요.

comp가 주어지면, 이 함수는 두 리스트 요소를 받아서 첫 번째 요소가 최종 순서에서 두 번째 요소보다 앞에 와야 할 때 true를 반환하는 함수여야 해요. 그래서 정렬이 끝난 뒤에는 i <= j이면 not comp(list[j], list[i])이 성립합니다.

comp가 주어지지 않으면 대신 표준 루아 연산자 <를 사용해요.

여기서 comp 함수가 정의해야 할 것은 일관된 순서, 더 정확히 말하면 **엄격한 약순서(strict weak order)**예요. (약순서는 전체순서(total order)와 비슷하지만, 비교 목적상 서로 다른 요소를 동등하게 취급할 수 있어요.)

한 가지 꼭 알아둘 점은, 이 정렬 알고리즘은 안정적이지 않다는 거예요. 주어진 순서 기준으로 동등하다고 간주된 서로 다른 요소들의 상대적 위치가 정렬 중에 바뀔 수 있습니다.


table.unpack (list [, i [, j]])

주어진 리스트의 요소들을 반환해요. 이 함수는 아래와 같아요:

return list[i], list[i+1], ···, list[j]

기본적으로 i는 1, j#list입니다.


6.7 – 수학 함수 (Mathematical Functions)

이 라이브러리는 기본적인 수학 함수를 제공해요. 모든 함수와 상수가 math 테이블 안에 담겨 있습니다.

"integer/float"로 표시된 함수들은 정수 인자에 대해선 정수 결과를, 비정수 인자에 대해선 실수(float) 결과를 돌려줘요. 반올림 함수 math.ceil, math.floor, math.modf는 결과가 정수 범위에 들어가면 정수를, 그렇지 않으면 실수를 반환합니다.


math.abs (x)

x-x 중 더 큰 값을 반환해요. (integer/float)


math.acos (x)

x의 아크코사인(역코사인) 값을 라디안(radian) 단위로 반환해요.


math.asin (x)

x의 아크사인(역사인) 값을 라디안 단위로 반환해요.


math.atan (y [, x])

y/x의 아크탄젠트 값을 라디안 단위로 반환해요. 이때 두 인자의 부호를 모두 사용해서 결과가 속한 사분면을 알아냅니다. x가 0인 경우도 올바르게 처리해요.

x의 기본값은 1이어서, math.atan(y)라고 호출하면 그냥 y의 아크탄젠트를 반환하게 됩니다.


math.ceil (x)

x보다 크거나 같은 가장 작은 정수 값을 반환해요.


math.cos (x)

x의 코사인 값을 반환해요. (x는 라디안이라고 가정해요.)


math.deg (x)

각도 x를 라디안에서 도(degree)로 변환해요.


math.exp (x)

ex제곱 값을 반환해요. (여기서 e는 자연로그의 밑이에요.)


math.floor (x)

x보다 작거나 같은 가장 큰 정수 값을 반환해요.


math.fmod (x, y)

xy로 나눈 나머지를 반환해요. 이때 몫은 0 방향으로 반올림됩니다. (integer/float)


math.huge

실수 값 HUGE_VAL, 즉 어떤 다른 수치 값보다도 큰 값이에요.


math.log (x [, base])

주어진 밑(base)에서 x의 로그 값을 반환해요. base의 기본값은 e이므로, 밑을 주지 않으면 자연로그(x의 자연로그)를 반환하게 됩니다.


math.max (x, ···)

루아 연산자 <에 따라 최댓값을 가진 인자를 반환해요.


math.maxinteger

정수 타입에서 가질 수 있는 최댓값을 나타내는 정수예요.


math.min (x, ···)

루아 연산자 <에 따라 최솟값을 가진 인자를 반환해요.


math.mininteger

정수 타입에서 가질 수 있는 최솟값을 나타내는 정수예요.


math.modf (x)

x의 정수 부분과 소수 부분을 반환해요. **두 번째 결과는 항상 실수(float)**입니다.


math.pi

원주율 π의 값이에요.


math.rad (x)

각도 x를 도에서 라디안으로 변환해요.


math.random ([m [, n]])

인자 없이 호출하면 [0, 1) 범위에서 균등 분포를 따르는 의사 난수 실수를 반환해요.

두 정수 m, n과 함께 호출하면 [m, n] 범위에서 균등 분포를 따르는 의사 난수 정수를 반환합니다. 양수 n에 대한 math.random(n) 호출은 math.random(1, n)과 동일해요. math.random(0) 호출은 모든 비트가 (의사)난수인 정수를 만들어냅니다.

이 함수는 의사 난수 64비트 정수(인자 0으로 호출했을 때의 결과)를 만들기 위해 xoshiro256** 알고리즘을 사용해요. 나머지 결과들(범위와 실수)은 이 정수들에서 편향 없이 추출됩니다.

루아는 프로그램을 실행할 때 인자 없는 math.randomseed 호출과 같은 형태로 의사 난수 생성기를 초기화해요. 그래서 math.random은 프로그램을 실행할 때마다 서로 다른 결과 시퀀스를 만들어 내야 합니다.


math.randomseed ([x [, y]])

인자를 적어도 하나 받아서 호출하면, 정수 파라미터 xy를 합쳐 **128비트 시드(seed)**를 만들고, 이를 사용해 의사 난수 생성기를 다시 초기화해요. 같은 시드는 같은 숫자 시퀀스를 만들어냅니다. y의 기본값은 0이에요.

인자 없이 호출하면 루아가 약한 수준의 무작위성으로 시드를 생성합니다.

이 함수는 실제로 사용된 두 시드 구성요소를 반환해요. 그래서 그 값을 다시 설정하면 같은 시퀀스를 반복할 수 있어요.

초기 상태에 필요한 수준의 무작위성을 보장하려면(또는 반대로, 예를 들어 프로그램을 디버깅할 때 결정적 시퀀스를 원한다면), math.randomseed명시적 인자와 함께 호출해야 합니다.


math.sin (x)

x의 사인 값을 반환해요. (x는 라디안이라고 가정해요.)


math.sqrt (x)

x의 제곱근을 반환해요. (이 값은 x^0.5 표현식으로도 구할 수 있어요.)


math.tan (x)

x의 탄젠트 값을 반환해요. (x는 라디안이라고 가정해요.)


math.tointeger (x)

x가 정수로 변환 가능하면 그 정수를 반환하고, 그렇지 않으면 fail을 반환해요.


math.type (x)

x가 정수면 "integer", 실수면 "float"를 반환하고, x가 숫자가 아니면 fail을 반환해요.


math.ult (m, n)

불리언 값을 반환해요. 두 정수 m, n부호 없는 정수(unsigned integer)로 비교했을 때 mn보다 작으면 true, 그렇지 않으면 false를 반환합니다.


더 알아보기

  • 테이블의 길이 연산자(#)table 함수들(특히 concat, insert, remove, sort의 기본값)이 길이를 어떻게 쓰는지 이해하려면 §3.4.7을 보는 게 좋아요. 길이 연산자가 항상 직관적이진 않다는 점을 꼭 확인해 두세요.
  • table.sort의 안정성 — 정렬 기준으로 동등한 요소들이 서로 위치가 바뀔 수 있어요. 원래 순서를 지켜야 한다면 별도로 추적할 방법을 마련해야 합니다.
  • 난수와 시드math.random은 xoshiro256** 기반이고, math.randomseed에 명시적 인자를 주면 같은 시퀀스를 재현할 수 있어요. 디버깅하거나 재현 가능한 실험이 필요할 때 유용합니다.
  • math.tointeger / math.type — 루아 5.3부터 정수와 실수를 구분하는 타입 개념이 들어왔어요. 숫자가 정수인지 실수인지, 변환될 수 있는지 판별할 때 이 함수들을 써요.