@@ -420,15 +420,15 @@ PHP_FUNCTION(bcmod)
420
420
/* {{{ Returns the value of an arbitrary precision number raised to the power of another reduced by a modulus */
421
421
PHP_FUNCTION (bcpowmod )
422
422
{
423
- zend_string * left , * right , * modulus ;
423
+ zend_string * base , * exponent , * modulus ;
424
424
zend_long scale_param ;
425
425
bool scale_param_is_null = 1 ;
426
- bc_num first , second , mod , result ;
426
+ bc_num bc_base , bc_expo , bc_modulus , result ;
427
427
int scale = BCG (bc_precision );
428
428
429
429
ZEND_PARSE_PARAMETERS_START (3 , 4 )
430
- Z_PARAM_STR (left )
431
- Z_PARAM_STR (right )
430
+ Z_PARAM_STR (base )
431
+ Z_PARAM_STR (exponent )
432
432
Z_PARAM_STR (modulus )
433
433
Z_PARAM_OPTIONAL
434
434
Z_PARAM_LONG_OR_NULL (scale_param , scale_param_is_null )
@@ -443,34 +443,53 @@ PHP_FUNCTION(bcpowmod)
443
443
scale = (int ) scale_param ;
444
444
}
445
445
446
- bc_init_num (& first );
447
- bc_init_num (& second );
448
- bc_init_num (& mod );
446
+ bc_init_num (& bc_base );
447
+ bc_init_num (& bc_expo );
448
+ bc_init_num (& bc_modulus );
449
449
bc_init_num (& result );
450
450
451
- if (php_str2num (& first , ZSTR_VAL (left )) == FAILURE ) {
451
+ if (php_str2num (& bc_base , ZSTR_VAL (base )) == FAILURE ) {
452
452
zend_argument_value_error (1 , "is not well-formed" );
453
453
goto cleanup ;
454
454
}
455
455
456
- if (php_str2num (& second , ZSTR_VAL (right )) == FAILURE ) {
456
+ if (php_str2num (& bc_expo , ZSTR_VAL (exponent )) == FAILURE ) {
457
457
zend_argument_value_error (2 , "is not well-formed" );
458
458
goto cleanup ;
459
459
}
460
460
461
- if (php_str2num (& mod , ZSTR_VAL (modulus )) == FAILURE ) {
461
+ if (php_str2num (& bc_modulus , ZSTR_VAL (modulus )) == FAILURE ) {
462
462
zend_argument_value_error (3 , "is not well-formed" );
463
463
goto cleanup ;
464
464
}
465
465
466
- if (bc_raisemod (first , second , mod , & result , scale ) == SUCCESS ) {
467
- RETVAL_STR (bc_num2str_ex (result , scale ));
466
+ raise_mod_status status = bc_raisemod (bc_base , bc_expo , bc_modulus , & result , scale );
467
+ switch (status ) {
468
+ case BASE_HAS_FRACTIONAL :
469
+ zend_argument_value_error (1 , "cannot have a fractional part" );
470
+ goto cleanup ;
471
+ case EXPO_HAS_FRACTIONAL :
472
+ zend_argument_value_error (2 , "cannot have a fractional part" );
473
+ goto cleanup ;
474
+ case EXPO_IS_NEGATIVE :
475
+ zend_argument_value_error (2 , "must be greater than or equal to 0" );
476
+ goto cleanup ;
477
+ case MOD_HAS_FRACTIONAL :
478
+ zend_argument_value_error (3 , "cannot have a fractional part" );
479
+ goto cleanup ;
480
+ case MOD_IS_ZERO :
481
+ zend_throw_exception_ex (zend_ce_division_by_zero_error , 0 , "Modulo by zero" );
482
+ goto cleanup ;
483
+ case OK :
484
+ RETVAL_STR (bc_num2str_ex (result , scale ));
485
+ break ;
486
+ EMPTY_SWITCH_DEFAULT_CASE ();
468
487
}
469
488
470
489
cleanup : {
471
- bc_free_num (& first );
472
- bc_free_num (& second );
473
- bc_free_num (& mod );
490
+ bc_free_num (& bc_base );
491
+ bc_free_num (& bc_expo );
492
+ bc_free_num (& bc_modulus );
474
493
bc_free_num (& result );
475
494
};
476
495
}
0 commit comments