authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-30 01:09:39-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-08-30 01:09:39-04:00
log427e2d689d34637bf7621be49beb7ec81b3fec0f
tree07c2f5d875684dcef32466dafa0615b5c5aa7826
parentac85befbb4356daa774b6083a3aa853b9c78f548
parente496485af4fe998a80564082fd7ea4556ed549e1
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #6189 from katesuyu/div-ceil

std: Add std.math.divCeil

1 files changed, 53 insertions(+), 0 deletions(-)

lib/std/math.zig+53
......@@ -596,6 +596,59 @@ fn testDivFloor() void {
596596 testing.expect((divFloor(f32, -5.0, 3.0) catch unreachable) == -2.0);
597597}
598598
599pub fn divCeil(comptime T: type, numerator: T, denominator: T) !T {
600 @setRuntimeSafety(false);
601 if (comptime std.meta.trait.isNumber(T) and denominator == 0) return error.DivisionByZero;
602 const info = @typeInfo(T);
603 switch (info) {
604 .ComptimeFloat, .Float => return @ceil(numerator / denominator),
605 .ComptimeInt, .Int => {
606 if (numerator < 0 and denominator < 0) {
607 if (info == .Int and numerator == minInt(T) and denominator == -1)
608 return error.Overflow;
609 return @divFloor(numerator + 1, denominator) + 1;
610 }
611 if (numerator > 0 and denominator > 0)
612 return @divFloor(numerator - 1, denominator) + 1;
613 return @divTrunc(numerator, denominator);
614 },
615 else => @compileError("divCeil unsupported on " ++ @typeName(T)),
616 }
617}
618
619test "math.divCeil" {
620 testDivCeil();
621 comptime testDivCeil();
622}
623fn testDivCeil() void {
624 testing.expectEqual(@as(i32, 2), divCeil(i32, 5, 3) catch unreachable);
625 testing.expectEqual(@as(i32, -1), divCeil(i32, -5, 3) catch unreachable);
626 testing.expectEqual(@as(i32, -1), divCeil(i32, 5, -3) catch unreachable);
627 testing.expectEqual(@as(i32, 2), divCeil(i32, -5, -3) catch unreachable);
628 testing.expectEqual(@as(i32, 0), divCeil(i32, 0, 5) catch unreachable);
629 testing.expectEqual(@as(u32, 0), divCeil(u32, 0, 5) catch unreachable);
630 testing.expectError(error.DivisionByZero, divCeil(i8, -5, 0));
631 testing.expectError(error.Overflow, divCeil(i8, -128, -1));
632
633 testing.expectEqual(@as(f32, 0.0), divCeil(f32, 0.0, 5.0) catch unreachable);
634 testing.expectEqual(@as(f32, 2.0), divCeil(f32, 5.0, 3.0) catch unreachable);
635 testing.expectEqual(@as(f32, -1.0), divCeil(f32, -5.0, 3.0) catch unreachable);
636 testing.expectEqual(@as(f32, -1.0), divCeil(f32, 5.0, -3.0) catch unreachable);
637 testing.expectEqual(@as(f32, 2.0), divCeil(f32, -5.0, -3.0) catch unreachable);
638
639 testing.expectEqual(6, divCeil(comptime_int, 23, 4) catch unreachable);
640 testing.expectEqual(-5, divCeil(comptime_int, -23, 4) catch unreachable);
641 testing.expectEqual(-5, divCeil(comptime_int, 23, -4) catch unreachable);
642 testing.expectEqual(6, divCeil(comptime_int, -23, -4) catch unreachable);
643 testing.expectError(error.DivisionByZero, divCeil(comptime_int, 23, 0));
644
645 testing.expectEqual(6.0, divCeil(comptime_float, 23.0, 4.0) catch unreachable);
646 testing.expectEqual(-5.0, divCeil(comptime_float, -23.0, 4.0) catch unreachable);
647 testing.expectEqual(-5.0, divCeil(comptime_float, 23.0, -4.0) catch unreachable);
648 testing.expectEqual(6.0, divCeil(comptime_float, -23.0, -4.0) catch unreachable);
649 testing.expectError(error.DivisionByZero, divCeil(comptime_float, 23.0, 0.0));
650}
651
599652pub fn divExact(comptime T: type, numerator: T, denominator: T) !T {
600653 @setRuntimeSafety(false);
601654 if (denominator == 0) return error.DivisionByZero;