| ... | @@ -623,12 +623,16 @@ fn testDivFloor() void { | ... | @@ -623,12 +623,16 @@ fn testDivFloor() void { |
| 623 | | 623 | |
| 624 | pub fn divCeil(comptime T: type, numerator: T, denominator: T) !T { | 624 | pub fn divCeil(comptime T: type, numerator: T, denominator: T) !T { |
| 625 | @setRuntimeSafety(false); | 625 | @setRuntimeSafety(false); |
| 626 | if (numerator <= 0) return divTrunc(T, numerator, denominator); | 626 | if (denominator == 0) return error.DivisionByZero; |
| 627 | if (@typeInfo(T) == .Float) { | 627 | if (@typeInfo(T) == .Float) return @ceil(numerator / denominator); |
| 628 | if (denominator == 0) return error.DivisionByZero; | 628 | if (T.is_signed and numerator < 0 and denominator < 0) { |
| 629 | return @ceil(numerator / denominator); | 629 | if (numerator == minInt(T) and denominator == -1) |
| | 630 | return error.Overflow; |
| | 631 | return @divFloor(numerator + 1, denominator) + 1; |
| 630 | } | 632 | } |
| 631 | return (try divFloor(T, numerator - 1, denominator)) + 1; | 633 | if (numerator > 0 and denominator > 0) |
| | 634 | return @divFloor(numerator - 1, denominator) + 1; |
| | 635 | return @divTrunc(numerator, denominator); |
| 632 | } | 636 | } |
| 633 | | 637 | |
| 634 | test "math.divCeil" { | 638 | test "math.divCeil" { |
| ... | @@ -638,11 +642,18 @@ test "math.divCeil" { | ... | @@ -638,11 +642,18 @@ test "math.divCeil" { |
| 638 | fn testDivCeil() void { | 642 | fn testDivCeil() void { |
| 639 | testing.expect((divCeil(i32, 5, 3) catch unreachable) == 2); | 643 | testing.expect((divCeil(i32, 5, 3) catch unreachable) == 2); |
| 640 | testing.expect((divCeil(i32, -5, 3) catch unreachable) == -1); | 644 | testing.expect((divCeil(i32, -5, 3) catch unreachable) == -1); |
| | 645 | testing.expect((divCeil(i32, 5, -3) catch unreachable) == -1); |
| | 646 | testing.expect((divCeil(i32, -5, -3) catch unreachable) == 2); |
| | 647 | testing.expect((divCeil(i32, 0, 5) catch unreachable) == 0); |
| | 648 | testing.expect((divCeil(u32, 0, 5) catch unreachable) == 0); |
| 641 | testing.expectError(error.DivisionByZero, divCeil(i8, -5, 0)); | 649 | testing.expectError(error.DivisionByZero, divCeil(i8, -5, 0)); |
| 642 | testing.expectError(error.Overflow, divCeil(i8, -128, -1)); | 650 | testing.expectError(error.Overflow, divCeil(i8, -128, -1)); |
| 643 | | 651 | |
| | 652 | testing.expect((divCeil(f32, 0.0, 5.0) catch unreachable) == 0.0); |
| 644 | testing.expect((divCeil(f32, 5.0, 3.0) catch unreachable) == 2.0); | 653 | testing.expect((divCeil(f32, 5.0, 3.0) catch unreachable) == 2.0); |
| 645 | testing.expect((divCeil(f32, -5.0, 3.0) catch unreachable) == -1.0); | 654 | testing.expect((divCeil(f32, -5.0, 3.0) catch unreachable) == -1.0); |
| | 655 | testing.expect((divCeil(f32, 5.0, -3.0) catch unreachable) == -1.0); |
| | 656 | testing.expect((divCeil(f32, -5.0, -3.0) catch unreachable) == 2.0); |
| 646 | } | 657 | } |
| 647 | | 658 | |
| 648 | pub fn divExact(comptime T: type, numerator: T, denominator: T) !T { | 659 | pub fn divExact(comptime T: type, numerator: T, denominator: T) !T { |