pub fn factorial(comptime Num: type, n: i8) ?Num { return if (@typeInfo(Num) != .Int) @compileError("factorial called with non-integral type: " ++ @typeName(Num)) else if (n < 0) null else calc: { var i: i8 = 1; var fac: Num = 1; while (i <= n) : (i += 1) { const tmp = @mulWithOverflow(fac, i); if (tmp[1] != 0) break :calc null; // overflow fac = tmp[0]; } else break :calc fac; }; } pub fn main() !void { const stdout = @import("std").io.getStdOut().writer(); try stdout.print("-1! = {?}\n", .{factorial(i32, -1)}); try stdout.print("0! = {?}\n", .{factorial(i32, 0)}); try stdout.print("5! = {?}\n", .{factorial(i32, 5)}); try stdout.print("33!(64 bit) = {?}\n", .{factorial(i64, 33)}); // not valid i64 factorial try stdout.print("33! = {?}\n", .{factorial(i128, 33)}); // biggest i128 factorial possible try stdout.print("34! = {?}\n", .{factorial(i128, 34)}); // will overflow }