@@ -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 ;
0 commit comments