@mod — 나머지 연산, 바닥 나눗셈 기준

@mod — 나머지 연산, 바닥 나눗셈 기준

나머지(modulus) 연산을 수행하는 내장 함수예요. 몫을 **음의 무한대 쪽으로 내림(floor)**한 뒤의 나머지를 돌려줘서, 부호를 따지는 연산에서 %와 헷갈리기 쉬워요.

출처: Zig Documentation

본문

@mod(numerator: T, denominator: T) T

@mod나머지 연산(modulus division) 을 하는 함수예요. 일단 간단한 경우부터 볼게요.

부호 없는 정수(unsigned integer)에 대해서는 numerator % denominator완전히 같은 결과를 줘요. 음수가 없으니 그냥 평범한 나머지 연산과 동일하다고 생각하면 돼요.

여기서 중요한 건 호출하는 쪽이 denominator != 0임을 보장해야 한다는 점이에요. 이 조건을 어기면, 런타임 안전성 검사(runtime safety checks)가 켜져 있을 때 Remainder Division by Zero 오류가 발생해요. 즉 0으로 나누면 안 되는 건 전적으로 내 책임이라는 뜻이에요.

핵심 성질을 보여주는 예시를 볼게요.

  • @mod(-5, 3) == 1 — 몫을 바닥 내림하면 -2가 되고, 남는 나머지가 1이 되어요.
  • (@divFloor(a, b) * b) + @mod(a, b) == a — 몫(@divFloor)과 나머지(@mod)를 합치면 항상 원래 값 a로 복원돼요.

여기서 @mod@rem(나머지)과 결정적인 차이가 있어요. @rem은 몫을 0으로 절사(truncate)한 뒤의 나머지라서 피연산자의 부호를 따라가요. 반면 @mod는 몫을 음의 무한대 쪽으로 내린 뒤의 나머지라서 항상 분모(denominator)의 부호를 따라가요. 그 결과 @mod(-5, 3)1이지만, @rem(-5, 3)-2가 돼요. 이 둘을 짝지어 쓰는 항등식도 달라요 — @rem(@divTrunc(a, b) * b) + @rem(a, b) == a꼴이고, @mod@divFloor와 짝을 이뤄요. 몫을 어느 쪽으로 내리느냐에 따라 그에 맞는 나머지 함수를 골라 써야 한다는 걸 기억해두면 좋아요.

만약 나눗셈이 실패했을 때 에러 코드(error code)를 받아서 처리하고 싶다면, 표준 라이브러리의 @import("std").math.mod를 사용하세요. 이건 오류를 반환할 수 있는 함수라서, 값을 미리 보장할 수 없는 상황에서는 이쪽이 더 안전해요.

더 알아보기(Learn more)

  • @rem — 같은 나머지 연산이지만 0으로 절사한 몫 기준이라서 부호가 @mod와 다르게 나와요. 부호 규칙을 꼭 비교해보세요.
  • @divFloor / @divTrunc@mod@rem이 각각 짝을 이루는 나눗셈 함수예요. 항등식 관계를 직접 검증해보면 이해가 빨라져요.