@@ -3050,24 +3050,45 @@ static Value builtin_div(Interpreter* interp, Value* args, int argc, Expr** arg_
30503050 return result ;
30513051}
30523052
3053- // CDIV: ceiling integer division (int-only semantics similar to Python's safe_cdiv )
3053+ // CDIV: ceiling division (supports INT and FLT; returns same numeric type )
30543054static Value builtin_cdiv (Interpreter * interp , Value * args , int argc , Expr * * arg_nodes , Env * env , int line , int col ) {
30553055 (void )arg_nodes ; (void )env ;
3056- EXPECT_INT (args [0 ], "CDIV" , interp , line , col );
3057- EXPECT_INT (args [1 ], "CDIV" , interp , line , col );
3056+ EXPECT_NUM (args [0 ], "CDIV" , interp , line , col );
3057+ EXPECT_NUM (args [1 ], "CDIV" , interp , line , col );
30583058
3059- int64_t a = args [0 ].as .i ;
3060- int64_t b = args [1 ].as .i ;
3061- if (b == 0 ) {
3062- RUNTIME_ERROR (interp , "Division by zero" , line , col );
3059+ if (args [0 ].type != args [1 ].type ) {
3060+ RUNTIME_ERROR (interp , "CDIV cannot mix INT and FLT" , line , col );
30633061 }
3064- double res = ceil ((double )a / (double )b );
3065- Value result = value_int ((int64_t )res );
3066- if (!writeback_ptr_range (interp , arg_nodes , env , 0 , 2 , result , "CDIV" , line , col )) {
3067- value_free (result );
3068- return value_null ();
3062+
3063+ int out_base = result_base_from_values (args [0 ], args [1 ]);
3064+
3065+ if (args [0 ].type == VAL_INT ) {
3066+ int64_t a = args [0 ].as .i ;
3067+ int64_t b = args [1 ].as .i ;
3068+ if (b == 0 ) {
3069+ RUNTIME_ERROR (interp , "Division by zero" , line , col );
3070+ }
3071+ int64_t q = a / b ;
3072+ int64_t r = a % b ;
3073+ if (r != 0 && ((a > 0 ) == (b > 0 ))) q += 1 ;
3074+ Value result = value_int_base (q , out_base );
3075+ if (!writeback_ptr_range (interp , arg_nodes , env , 0 , 2 , result , "CDIV" , line , col )) {
3076+ value_free (result );
3077+ return value_null ();
3078+ }
3079+ return result ;
3080+ } else {
3081+ if (args [1 ].as .f == 0.0 ) {
3082+ RUNTIME_ERROR (interp , "Division by zero" , line , col );
3083+ }
3084+ double res = ceil (args [0 ].as .f / args [1 ].as .f );
3085+ Value result = value_flt_base (res , out_base );
3086+ if (!writeback_ptr_range (interp , arg_nodes , env , 0 , 2 , result , "CDIV" , line , col )) {
3087+ value_free (result );
3088+ return value_null ();
3089+ }
3090+ return result ;
30693091 }
3070- return result ;
30713092}
30723093
30733094static Value builtin_mod (Interpreter * interp , Value * args , int argc , Expr * * arg_nodes , Env * env , int line , int col ) {
0 commit comments