| ... | ... | @@ -596,6 +596,59 @@ fn testDivFloor() void { |
| 596 | 596 | testing.expect((divFloor(f32, -5.0, 3.0) catch unreachable) == -2.0); |
| 597 | 597 | } |
| 598 | 598 | |
| 599 | pub 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 | |
| 619 | test "math.divCeil" { |
| 620 | testDivCeil(); |
| 621 | comptime testDivCeil(); |
| 622 | } |
| 623 | fn 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 | |
| 599 | 652 | pub fn divExact(comptime T: type, numerator: T, denominator: T) !T { |
| 600 | 653 | @setRuntimeSafety(false); |
| 601 | 654 | if (denominator == 0) return error.DivisionByZero; |