const std = @import("std"); pub fn add(a: anytype, b: anytype) ?@TypeOf(a + b) { const result, const overflow = @addWithOverflow(a, b); return if (overflow == 0) result else null; } pub fn fractional(value: anytype, fraction: anytype) ?@TypeOf(value) { if (fraction < 0 or fraction > 1) { return null; } const Fraction = @TypeOf(fraction); return switch (@typeInfo(Fraction)) { .Float => @intFromFloat(@as(Fraction, @floatFromInt(value)) * fraction), else => @compileError("`fraction` expected float type, not " ++ @typeName(Fraction)), }; } pub fn lerp_angle(origin_angle: anytype, target_angle: anytype, weight: anytype) @TypeOf(origin_angle, target_angle, weight) { const angle_difference = @mod(target_angle - origin_angle, std.math.tau); const distance = @mod(2.0 * angle_difference, std.math.tau) - angle_difference; return origin_angle + distance * weight; } pub fn mul(a: anytype, b: anytype) ?@TypeOf(a * b) { const result, const overflow = @mulWithOverflow(a, b); return if (overflow == 0) result else null; } pub fn sub(a: anytype, b: anytype) ?@TypeOf(a - b) { const result, const overflow = @subWithOverflow(a, b); return if (overflow == 0) result else null; }