This source file includes following definitions.
- ZEND_TSRMLS_CACHE_DEFINE
- PHP_GSHUTDOWN_FUNCTION
- PHP_MINIT_FUNCTION
- PHP_MSHUTDOWN_FUNCTION
- PHP_MINFO_FUNCTION
- php_str2num
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "php.h"
26
27 #if HAVE_BCMATH
28
29 #include "php_ini.h"
30 #include "ext/standard/info.h"
31 #include "php_bcmath.h"
32 #include "libbcmath/src/bcmath.h"
33
34 ZEND_DECLARE_MODULE_GLOBALS(bcmath)
35 static PHP_GINIT_FUNCTION(bcmath);
36 static PHP_GSHUTDOWN_FUNCTION(bcmath);
37
38
39 ZEND_BEGIN_ARG_INFO_EX(arginfo_bcadd, 0, 0, 2)
40 ZEND_ARG_INFO(0, left_operand)
41 ZEND_ARG_INFO(0, right_operand)
42 ZEND_ARG_INFO(0, scale)
43 ZEND_END_ARG_INFO()
44
45 ZEND_BEGIN_ARG_INFO_EX(arginfo_bcsub, 0, 0, 2)
46 ZEND_ARG_INFO(0, left_operand)
47 ZEND_ARG_INFO(0, right_operand)
48 ZEND_ARG_INFO(0, scale)
49 ZEND_END_ARG_INFO()
50
51 ZEND_BEGIN_ARG_INFO_EX(arginfo_bcmul, 0, 0, 2)
52 ZEND_ARG_INFO(0, left_operand)
53 ZEND_ARG_INFO(0, right_operand)
54 ZEND_ARG_INFO(0, scale)
55 ZEND_END_ARG_INFO()
56
57 ZEND_BEGIN_ARG_INFO_EX(arginfo_bcdiv, 0, 0, 2)
58 ZEND_ARG_INFO(0, left_operand)
59 ZEND_ARG_INFO(0, right_operand)
60 ZEND_ARG_INFO(0, scale)
61 ZEND_END_ARG_INFO()
62
63 ZEND_BEGIN_ARG_INFO(arginfo_bcmod, 0)
64 ZEND_ARG_INFO(0, left_operand)
65 ZEND_ARG_INFO(0, right_operand)
66 ZEND_END_ARG_INFO()
67
68 ZEND_BEGIN_ARG_INFO_EX(arginfo_bcpowmod, 0, 0, 3)
69 ZEND_ARG_INFO(0, x)
70 ZEND_ARG_INFO(0, y)
71 ZEND_ARG_INFO(0, mod)
72 ZEND_ARG_INFO(0, scale)
73 ZEND_END_ARG_INFO()
74
75 ZEND_BEGIN_ARG_INFO_EX(arginfo_bcpow, 0, 0, 2)
76 ZEND_ARG_INFO(0, x)
77 ZEND_ARG_INFO(0, y)
78 ZEND_ARG_INFO(0, scale)
79 ZEND_END_ARG_INFO()
80
81 ZEND_BEGIN_ARG_INFO_EX(arginfo_bcsqrt, 0, 0, 1)
82 ZEND_ARG_INFO(0, operand)
83 ZEND_ARG_INFO(0, scale)
84 ZEND_END_ARG_INFO()
85
86 ZEND_BEGIN_ARG_INFO_EX(arginfo_bccomp, 0, 0, 2)
87 ZEND_ARG_INFO(0, left_operand)
88 ZEND_ARG_INFO(0, right_operand)
89 ZEND_ARG_INFO(0, scale)
90 ZEND_END_ARG_INFO()
91
92 ZEND_BEGIN_ARG_INFO(arginfo_bcscale, 0)
93 ZEND_ARG_INFO(0, scale)
94 ZEND_END_ARG_INFO()
95
96
97
98 const zend_function_entry bcmath_functions[] = {
99 PHP_FE(bcadd, arginfo_bcadd)
100 PHP_FE(bcsub, arginfo_bcsub)
101 PHP_FE(bcmul, arginfo_bcmul)
102 PHP_FE(bcdiv, arginfo_bcdiv)
103 PHP_FE(bcmod, arginfo_bcmod)
104 PHP_FE(bcpow, arginfo_bcpow)
105 PHP_FE(bcsqrt, arginfo_bcsqrt)
106 PHP_FE(bcscale, arginfo_bcscale)
107 PHP_FE(bccomp, arginfo_bccomp)
108 PHP_FE(bcpowmod, arginfo_bcpowmod)
109 PHP_FE_END
110 };
111
112 zend_module_entry bcmath_module_entry = {
113 STANDARD_MODULE_HEADER,
114 "bcmath",
115 bcmath_functions,
116 PHP_MINIT(bcmath),
117 PHP_MSHUTDOWN(bcmath),
118 NULL,
119 NULL,
120 PHP_MINFO(bcmath),
121 PHP_BCMATH_VERSION,
122 PHP_MODULE_GLOBALS(bcmath),
123 PHP_GINIT(bcmath),
124 PHP_GSHUTDOWN(bcmath),
125 NULL,
126 STANDARD_MODULE_PROPERTIES_EX
127 };
128
129 #ifdef COMPILE_DL_BCMATH
130 #ifdef ZTS
131 ZEND_TSRMLS_CACHE_DEFINE()
132 #endif
133 ZEND_GET_MODULE(bcmath)
134 #endif
135
136
137 PHP_INI_BEGIN()
138 STD_PHP_INI_ENTRY("bcmath.scale", "0", PHP_INI_ALL, OnUpdateLongGEZero, bc_precision, zend_bcmath_globals, bcmath_globals)
139 PHP_INI_END()
140
141
142
143
144 static PHP_GINIT_FUNCTION(bcmath)
145 {
146 #if defined(COMPILE_DL_BCMATH) && defined(ZTS)
147 ZEND_TSRMLS_CACHE_UPDATE();
148 #endif
149 bcmath_globals->bc_precision = 0;
150 bc_init_numbers();
151 }
152
153
154
155
156 static PHP_GSHUTDOWN_FUNCTION(bcmath)
157 {
158 _bc_free_num_ex(&bcmath_globals->_zero_, 1);
159 _bc_free_num_ex(&bcmath_globals->_one_, 1);
160 _bc_free_num_ex(&bcmath_globals->_two_, 1);
161 }
162
163
164
165
166 PHP_MINIT_FUNCTION(bcmath)
167 {
168 REGISTER_INI_ENTRIES();
169
170 return SUCCESS;
171 }
172
173
174
175
176 PHP_MSHUTDOWN_FUNCTION(bcmath)
177 {
178 UNREGISTER_INI_ENTRIES();
179
180 return SUCCESS;
181 }
182
183
184
185
186 PHP_MINFO_FUNCTION(bcmath)
187 {
188 php_info_print_table_start();
189 php_info_print_table_row(2, "BCMath support", "enabled");
190 php_info_print_table_end();
191 DISPLAY_INI_ENTRIES();
192 }
193
194
195
196
197 static void php_str2num(bc_num *num, char *str)
198 {
199 char *p;
200
201 if (!(p = strchr(str, '.'))) {
202 bc_str2num(num, str, 0);
203 return;
204 }
205
206 bc_str2num(num, str, strlen(p+1));
207 }
208
209
210
211
212 PHP_FUNCTION(bcadd)
213 {
214 char *left, *right;
215 zend_long scale_param = 0;
216 bc_num first, second, result;
217 size_t left_len, right_len;
218 int scale = (int)BCG(bc_precision), argc = ZEND_NUM_ARGS();
219
220 if (zend_parse_parameters(argc, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) {
221 return;
222 }
223
224 if (argc == 3) {
225 scale = (int) (scale_param < 0 ? 0 : scale_param);
226 }
227
228 bc_init_num(&first);
229 bc_init_num(&second);
230 bc_init_num(&result);
231 php_str2num(&first, left);
232 php_str2num(&second, right);
233 bc_add (first, second, &result, scale);
234
235 if (result->n_scale > scale) {
236 result->n_scale = scale;
237 }
238
239 RETVAL_STR(bc_num2str(result));
240 bc_free_num(&first);
241 bc_free_num(&second);
242 bc_free_num(&result);
243 return;
244 }
245
246
247
248
249 PHP_FUNCTION(bcsub)
250 {
251 char *left, *right;
252 size_t left_len, right_len;
253 zend_long scale_param = 0;
254 bc_num first, second, result;
255 int scale = (int)BCG(bc_precision), argc = ZEND_NUM_ARGS();
256
257 if (zend_parse_parameters(argc, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) {
258 return;
259 }
260
261 if (argc == 3) {
262 scale = (int) ((int)scale_param < 0 ? 0 : scale_param);
263 }
264
265 bc_init_num(&first);
266 bc_init_num(&second);
267 bc_init_num(&result);
268 php_str2num(&first, left);
269 php_str2num(&second, right);
270 bc_sub (first, second, &result, scale);
271
272 if (result->n_scale > scale) {
273 result->n_scale = scale;
274 }
275
276 RETVAL_STR(bc_num2str(result));
277 bc_free_num(&first);
278 bc_free_num(&second);
279 bc_free_num(&result);
280 return;
281 }
282
283
284
285
286 PHP_FUNCTION(bcmul)
287 {
288 char *left, *right;
289 size_t left_len, right_len;
290 zend_long scale_param = 0;
291 bc_num first, second, result;
292 int scale = (int)BCG(bc_precision), argc = ZEND_NUM_ARGS();
293
294 if (zend_parse_parameters(argc, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) {
295 return;
296 }
297
298 if (argc == 3) {
299 scale = (int) ((int)scale_param < 0 ? 0 : scale_param);
300 }
301
302 bc_init_num(&first);
303 bc_init_num(&second);
304 bc_init_num(&result);
305 php_str2num(&first, left);
306 php_str2num(&second, right);
307 bc_multiply (first, second, &result, scale);
308
309 if (result->n_scale > scale) {
310 result->n_scale = scale;
311 }
312
313 RETVAL_STR(bc_num2str(result));
314 bc_free_num(&first);
315 bc_free_num(&second);
316 bc_free_num(&result);
317 return;
318 }
319
320
321
322
323 PHP_FUNCTION(bcdiv)
324 {
325 char *left, *right;
326 size_t left_len, right_len;
327 zend_long scale_param = 0;
328 bc_num first, second, result;
329 int scale = (int)BCG(bc_precision), argc = ZEND_NUM_ARGS();
330
331 if (zend_parse_parameters(argc, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) {
332 return;
333 }
334
335 if (argc == 3) {
336 scale = (int) ((int)scale_param < 0 ? 0 : scale_param);
337 }
338
339 bc_init_num(&first);
340 bc_init_num(&second);
341 bc_init_num(&result);
342 php_str2num(&first, left);
343 php_str2num(&second, right);
344
345 switch (bc_divide(first, second, &result, scale)) {
346 case 0:
347 if (result->n_scale > scale) {
348 result->n_scale = scale;
349 }
350 RETVAL_STR(bc_num2str(result));
351 break;
352 case -1:
353 php_error_docref(NULL, E_WARNING, "Division by zero");
354 break;
355 }
356
357 bc_free_num(&first);
358 bc_free_num(&second);
359 bc_free_num(&result);
360 return;
361 }
362
363
364
365
366 PHP_FUNCTION(bcmod)
367 {
368 char *left, *right;
369 size_t left_len, right_len;
370 bc_num first, second, result;
371
372 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &left, &left_len, &right, &right_len) == FAILURE) {
373 return;
374 }
375
376 bc_init_num(&first);
377 bc_init_num(&second);
378 bc_init_num(&result);
379 bc_str2num(&first, left, 0);
380 bc_str2num(&second, right, 0);
381
382 switch (bc_modulo(first, second, &result, 0)) {
383 case 0:
384 RETVAL_STR(bc_num2str(result));
385 break;
386 case -1:
387 php_error_docref(NULL, E_WARNING, "Division by zero");
388 break;
389 }
390
391 bc_free_num(&first);
392 bc_free_num(&second);
393 bc_free_num(&result);
394 return;
395 }
396
397
398
399
400 PHP_FUNCTION(bcpowmod)
401 {
402 char *left, *right, *modulous;
403 size_t left_len, right_len, modulous_len;
404 bc_num first, second, mod, result;
405 zend_long scale = BCG(bc_precision);
406 int scale_int;
407
408 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|l", &left, &left_len, &right, &right_len, &modulous, &modulous_len, &scale) == FAILURE) {
409 return;
410 }
411
412 bc_init_num(&first);
413 bc_init_num(&second);
414 bc_init_num(&mod);
415 bc_init_num(&result);
416 php_str2num(&first, left);
417 php_str2num(&second, right);
418 php_str2num(&mod, modulous);
419
420 scale_int = (int) ((int)scale < 0 ? 0 : scale);
421
422 if (bc_raisemod(first, second, mod, &result, scale_int) != -1) {
423 if (result->n_scale > scale) {
424 result->n_scale = (int)scale;
425 }
426 RETVAL_STR(bc_num2str(result));
427 } else {
428 RETVAL_FALSE;
429 }
430
431 bc_free_num(&first);
432 bc_free_num(&second);
433 bc_free_num(&mod);
434 bc_free_num(&result);
435 return;
436 }
437
438
439
440
441 PHP_FUNCTION(bcpow)
442 {
443 char *left, *right;
444 size_t left_len, right_len;
445 zend_long scale_param = 0;
446 bc_num first, second, result;
447 int scale = (int)BCG(bc_precision), argc = ZEND_NUM_ARGS();
448
449 if (zend_parse_parameters(argc, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) {
450 return;
451 }
452
453 if (argc == 3) {
454 scale = (int) ((int)scale_param < 0 ? 0 : scale_param);
455 }
456
457 bc_init_num(&first);
458 bc_init_num(&second);
459 bc_init_num(&result);
460 php_str2num(&first, left);
461 php_str2num(&second, right);
462 bc_raise (first, second, &result, scale);
463
464 if (result->n_scale > scale) {
465 result->n_scale = scale;
466 }
467
468 RETVAL_STR(bc_num2str(result));
469 bc_free_num(&first);
470 bc_free_num(&second);
471 bc_free_num(&result);
472 return;
473 }
474
475
476
477
478 PHP_FUNCTION(bcsqrt)
479 {
480 char *left;
481 size_t left_len;
482 zend_long scale_param = 0;
483 bc_num result;
484 int scale = (int)BCG(bc_precision), argc = ZEND_NUM_ARGS();
485
486 if (zend_parse_parameters(argc, "s|l", &left, &left_len, &scale_param) == FAILURE) {
487 return;
488 }
489
490 if (argc == 2) {
491 scale = (int) ((int)scale_param < 0 ? 0 : scale_param);
492 }
493
494 bc_init_num(&result);
495 php_str2num(&result, left);
496
497 if (bc_sqrt (&result, scale) != 0) {
498 if (result->n_scale > scale) {
499 result->n_scale = scale;
500 }
501 RETVAL_STR(bc_num2str(result));
502 } else {
503 php_error_docref(NULL, E_WARNING, "Square root of negative number");
504 }
505
506 bc_free_num(&result);
507 return;
508 }
509
510
511
512
513 PHP_FUNCTION(bccomp)
514 {
515 char *left, *right;
516 size_t left_len, right_len;
517 zend_long scale_param = 0;
518 bc_num first, second;
519 int scale = (int)BCG(bc_precision), argc = ZEND_NUM_ARGS();
520
521 if (zend_parse_parameters(argc, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) {
522 return;
523 }
524
525 if (argc == 3) {
526 scale = (int) ((int)scale_param < 0 ? 0 : scale_param);
527 }
528
529 bc_init_num(&first);
530 bc_init_num(&second);
531
532 bc_str2num(&first, left, scale);
533 bc_str2num(&second, right, scale);
534 RETVAL_LONG(bc_compare(first, second));
535
536 bc_free_num(&first);
537 bc_free_num(&second);
538 return;
539 }
540
541
542
543
544 PHP_FUNCTION(bcscale)
545 {
546 zend_long new_scale;
547
548 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &new_scale) == FAILURE) {
549 return;
550 }
551
552 BCG(bc_precision) = ((int)new_scale < 0) ? 0 : new_scale;
553
554 RETURN_TRUE;
555 }
556
557
558
559 #endif
560
561
562
563
564
565
566
567
568