36
36
#include <stdarg.h>
37
37
#include "bcmath.h"
38
38
#include "private.h"
39
+ #include "zend_exceptions.h"
39
40
40
-
41
- /* Truncate a number to zero scale. To avoid sharing issues (refcount and
42
- shared n_value) the number is copied, this copy is truncated, and the
43
- original number is "freed". */
44
-
45
- static void
46
- _bc_truncate (bc_num * num )
47
- {
48
- bc_num temp ;
49
-
50
- temp = bc_new_num ((* num )-> n_len , 0 );
51
- temp -> n_sign = (* num )-> n_sign ;
52
- memcpy (temp -> n_value , (* num )-> n_value , (* num )-> n_len );
53
- bc_free_num (num );
54
- * num = temp ;
55
- }
56
-
57
-
58
- /* Raise BASE to the EXPO power, reduced modulo MOD. The result is
59
- placed in RESULT. If a EXPO is not an integer,
60
- only the integer part is used. */
61
-
62
- int
63
- bc_raisemod (bc_num base , bc_num expo , bc_num mod , bc_num * result , int scale )
41
+ /* Raise BASE to the EXPO power, reduced modulo MOD. The result is placed in RESULT. */
42
+ zend_result bc_raisemod (bc_num base , bc_num expo , bc_num mod , bc_num * result , int scale )
64
43
{
65
44
bc_num power , exponent , modulus , parity , temp ;
66
45
int rscale ;
67
46
68
- /* Check for correct numbers. */
69
- if (bc_is_zero (mod )) return -1 ;
70
- if (bc_is_neg (expo )) return -2 ;
47
+ /* Check the base for scale digits. */
48
+ if (base -> n_scale != 0 ) {
49
+ /* 1st argument from PHP_FUNCTION(bcpowmod) */
50
+ zend_argument_value_error (1 , "cannot have a fractional part" );
51
+ return FAILURE ;
52
+ }
53
+ /* Check the exponent for scale digits. */
54
+ if (expo -> n_scale != 0 ) {
55
+ /* 2nd argument from PHP_FUNCTION(bcpowmod) */
56
+ zend_argument_value_error (2 , "cannot have a fractional part" );
57
+ return FAILURE ;
58
+ }
59
+ if (bc_is_neg (expo )) {
60
+ zend_argument_value_error (2 , "must be greater than or equal to 0" );
61
+ return FAILURE ;
62
+ }
63
+ /* Check the modulus for scale digits. */
64
+ if (mod -> n_scale != 0 ) {
65
+ /* 3rd argument from PHP_FUNCTION(bcpowmod) */
66
+ zend_argument_value_error (3 , "cannot have a fractional part" );
67
+ return FAILURE ;
68
+ }
69
+ /* Modulus cannot be 0 */
70
+ if (bc_is_zero (mod )) {
71
+ zend_throw_exception_ex (zend_ce_division_by_zero_error , 0 , "Modulo by zero" );
72
+ return FAILURE ;
73
+ }
71
74
72
75
/* Set initial values. */
73
76
power = bc_copy_num (base );
@@ -76,27 +79,6 @@ bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale)
76
79
temp = bc_copy_num (BCG (_one_ ));
77
80
bc_init_num (& parity );
78
81
79
- /* Check the base for scale digits. */
80
- if (power -> n_scale != 0 )
81
- {
82
- php_error_docref (NULL , E_WARNING , "Non-zero scale in base" );
83
- _bc_truncate (& power );
84
- }
85
-
86
- /* Check the exponent for scale digits. */
87
- if (exponent -> n_scale != 0 )
88
- {
89
- php_error_docref (NULL , E_WARNING , "Non-zero scale in exponent" );
90
- _bc_truncate (& exponent );
91
- }
92
-
93
- /* Check the modulus for scale digits. */
94
- if (modulus -> n_scale != 0 )
95
- {
96
- php_error_docref (NULL , E_WARNING , "Non-zero scale in modulus" );
97
- _bc_truncate (& modulus );
98
- }
99
-
100
82
/* Do the calculation. */
101
83
rscale = MAX (scale , power -> n_scale );
102
84
if ( !bc_compare (modulus , BCG (_one_ )) )
@@ -127,5 +109,5 @@ bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale)
127
109
bc_free_num (result );
128
110
bc_free_num (& parity );
129
111
* result = temp ;
130
- return 0 ; /* Everything is OK. */
112
+ return SUCCESS ; /* Everything is OK. */
131
113
}
0 commit comments