Exact Division Remainder — 정확히 나눠떨어질 때만 쓰는 나눗셈
Exact Division Remainder — 정확히 나눠떨어질 때만 쓰는 나눗셈
본문
@divExact는 이름 그대로 나눗셈이 정확히 나눠떨어질 때만 쓰는 내장 함수예요. 이전에 다뤘던 나눗셈 계열 내장 함수들과 다른 점은, 결과에 나머지가 생기면 안 된다는 조건이 걸려 있다는 거예요. 그러면 정확히 나눠떨어지지 않을 때는 어떤 일이 벌어질까요? 컴파일 타임과 런타임에서 그 모습이 조금 달라요. 하나씩 볼게요.
먼저 컴파일 타임(comptime) 상황입니다.
컴파일 타임:
comptime {
const a: u32 = 10;
const b: u32 = 3;
const c = @divExact(a, b);
_ = c;
}
여기서 10을 3으로 나누면 몫은 3이고 나머지 1이 남죠. 정확히 나눠떨어지지 않으니 컴파일러가 이걸 검사해서 컴파일 에러로 처리해요.
$ zig test test_comptime_divExact_remainder.zig
/home/ci/work/zig-bootstrap/zig/doc/langref/test_comptime_divExact_remainder.zig:4:15: error: exact division produced remainder
const c = @divExact(a, b);
^~~~~~~~~~~~~~~
이제 런타임 상황을 볼게요.
런타임:
const std = @import("std");
pub fn main() void {
var a: u32 = 10;
var b: u32 = 3;
_ = .{ &a, &b };
const c = @divExact(a, b);
std.debug.print("value: {}\n", .{c});
}
여기서는 a와 b가 var로 선언돼 있어서 값이 컴파일 타임에 확정되지 않아요. 그래서 컴파일러가 미리 검사할 수 없고, 프로그램이 실제로 실행되는 순간까지 갑니다. 실행하면 기대만큼 value: 3 같은 값이 찍히는 게 아니라, 나눗셈에 나머지가 생겼다며 패닉(panic) 이 발생해요.
$ zig build-exe runtime_divExact_remainder.zig
$ ./runtime_divExact_remainder
thread 973431 panic: exact division produced remainder
/home/ci/work/zig-bootstrap/zig/doc/langref/runtime_divExact_remainder.zig:7:15: 0x11e82e5 in main (runtime_divExact_remainder.zig)
const c = @divExact(a, b);
^
/home/ci/work/zig-bootstrap/out/host/lib/zig/std/start.zig:788:64: 0x11e7bbb in callMain (std.zig)
if (fn_info.param_types.len == 0) return wrapMain(root.main());
^
/home/ci/work/zig-bootstrap/out/host/lib/zig/std/start.zig:248:5: 0x11e75e1 in _start (std.zig)
asm volatile (switch (native_arch) {
^
(process terminated by signal)
정리하면 이렇게 볼 수 있어요. @divExact는 나눠떨어지는 게 보장된 값에만 써야 해요. 만약 나머지가 생길 가능성이 있는 경우라면, 나눗셈 결과가 정확하다는 게 컴파일 타임에는 보장되지 않으니 런타임 패닉까지 이어질 수 있다는 점을 미리 인지하고 있어야 하죠. 값이 컴파일 타임에 알려진 상수라면 컴파일 에러, 실행 시에야 알 수 있는 값이라면 런타임 패닉으로 잡힌다는 차이만 기억하면 돼요.
더 알아보기
@divExact는 나머지 없이 정확히 나눠떨어지는 나눗셈을 수행하고, 나머지가 생기면 컴파일 에러 또는 런타임 패닉으로 이어져요.- 컴파일 타임 검사가 가능한(
comptime) 값은 에러로, 실행 중에만 알 수 있는 값은 패닉으로 처리돼요. - 나머지가 있어도 되는 일반적인 나눗셈에는
@divFloor·@divTrunc같은 다른 내장 함수를 써요.