| ... | ... | @@ -624,15 +624,21 @@ fn testDivFloor() void { |
| 624 | 624 | pub fn divCeil(comptime T: type, numerator: T, denominator: T) !T { |
| 625 | 625 | @setRuntimeSafety(false); |
| 626 | 626 | if (denominator == 0) return error.DivisionByZero; |
| 627 | | if (@typeInfo(T) == .Float) return @ceil(numerator / denominator); |
| 628 | | if (T.is_signed and numerator < 0 and denominator < 0) { |
| 629 | | if (numerator == minInt(T) and denominator == -1) |
| 630 | | return error.Overflow; |
| 631 | | return @divFloor(numerator + 1, denominator) + 1; |
| 627 | const info = @typeInfo(T); |
| 628 | switch (info) { |
| 629 | .ComptimeFloat, .Float => return @ceil(numerator / denominator), |
| 630 | .ComptimeInt, .Int => { |
| 631 | if (numerator < 0 and denominator < 0) { |
| 632 | if (info == .Int and numerator == minInt(T) and denominator == -1) |
| 633 | return error.Overflow; |
| 634 | return @divFloor(numerator + 1, denominator) + 1; |
| 635 | } |
| 636 | if (numerator > 0 and denominator > 0) |
| 637 | return @divFloor(numerator - 1, denominator) + 1; |
| 638 | return @divTrunc(numerator, denominator); |
| 639 | }, |
| 640 | else => @compileError("divCeil unsupported on " ++ @typeName(T)), |
| 632 | 641 | } |
| 633 | | if (numerator > 0 and denominator > 0) |
| 634 | | return @divFloor(numerator - 1, denominator) + 1; |
| 635 | | return @divTrunc(numerator, denominator); |
| 636 | 642 | } |
| 637 | 643 | |
| 638 | 644 | test "math.divCeil" { |
| ... | ... | @@ -654,6 +660,18 @@ fn testDivCeil() void { |
| 654 | 660 | testing.expect((divCeil(f32, -5.0, 3.0) catch unreachable) == -1.0); |
| 655 | 661 | testing.expect((divCeil(f32, 5.0, -3.0) catch unreachable) == -1.0); |
| 656 | 662 | testing.expect((divCeil(f32, -5.0, -3.0) catch unreachable) == 2.0); |
| 663 | |
| 664 | testing.expect((divCeil(comptime_int, 23, 4) catch unreachable) == 6); |
| 665 | testing.expect((divCeil(comptime_int, -23, 4) catch unreachable) == -5); |
| 666 | testing.expect((divCeil(comptime_int, 23, -4) catch unreachable) == -5); |
| 667 | testing.expect((divCeil(comptime_int, -23, -4) catch unreachable) == 6); |
| 668 | testing.expectError(error.DivisionByZero, divCeil(comptime_int, 23, 0)); |
| 669 | |
| 670 | testing.expect((divCeil(comptime_float, 23.0, 4.0) catch unreachable) == 6.0); |
| 671 | testing.expect((divCeil(comptime_float, -23.0, 4.0) catch unreachable) == -5.0); |
| 672 | testing.expect((divCeil(comptime_float, 23.0, -4.0) catch unreachable) == -5.0); |
| 673 | testing.expect((divCeil(comptime_float, -23.0, -4.0) catch unreachable) == 6.0); |
| 674 | testing.expectError(error.DivisionByZero, divCeil(comptime_float, 23.0, 0.0)); |
| 657 | 675 | } |
| 658 | 676 | |
| 659 | 677 | pub fn divExact(comptime T: type, numerator: T, denominator: T) !T { |