RosettaCodeData/Task/Factorial/Zig/factorial.zig

28 lines
1.0 KiB
Zig

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
}