PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/standard - math.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 410 450 91.1 %
Date: 2014-08-04 Functions: 56 57 98.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 5                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2014 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Jim Winstead <jimw@php.net>                                 |
      16             :    |          Stig Sæther Bakken <ssb@php.net>                            |
      17             :    |          Zeev Suraski <zeev@zend.com>                                |
      18             :    | PHP 4.0 patches by Thies C. Arntzen <thies@thieso.net>               |
      19             :    +----------------------------------------------------------------------+
      20             : */
      21             : 
      22             : /* $Id$ */
      23             : 
      24             : #include "php.h"
      25             : #include "php_math.h"
      26             : #include "zend_multiply.h"
      27             : 
      28             : #include <math.h>
      29             : #include <float.h>
      30             : #include <stdlib.h>
      31             : 
      32             : #include "basic_functions.h"
      33             : 
      34             : /* {{{ php_intlog10abs
      35             :    Returns floor(log10(fabs(val))), uses fast binary search */
      36        1507 : static inline int php_intlog10abs(double value) {
      37             :         int result;
      38        1507 :         value = fabs(value);
      39             : 
      40        1545 :         if (value < 1e-8 || value > 1e22) {
      41          38 :                 result = (int)floor(log10(value));
      42             :         } else {
      43             :                 static const double values[] = {
      44             :                         1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,
      45             :                         1e0,  1e1,  1e2,  1e3,  1e4,  1e5,  1e6,  1e7,
      46             :                         1e8,  1e9,  1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
      47             :                         1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
      48             :                 /* Do a binary search with 5 steps */
      49        1469 :                 result = 15;
      50        1469 :                 if (value < values[result]) {
      51        1389 :                         result -= 8;
      52             :                 } else {
      53          80 :                         result += 8;
      54             :                 }
      55        1469 :                 if (value < values[result]) {
      56          84 :                         result -= 4;
      57             :                 } else {
      58        1385 :                         result += 4;
      59             :                 }
      60        1469 :                 if (value < values[result]) {
      61         758 :                         result -= 2;
      62             :                 } else {
      63         711 :                         result += 2;
      64             :                 }
      65        1469 :                 if (value < values[result]) {
      66         738 :                         result -= 1;
      67             :                 } else {
      68         731 :                         result += 1;
      69             :                 }
      70        1469 :                 if (value < values[result]) {
      71         662 :                         result -= 1;
      72             :                 }
      73        1469 :                 result -= 8;
      74             :         }
      75        1507 :         return result;
      76             : }
      77             : /* }}} */
      78             : 
      79             : /* {{{ php_intpow10
      80             :        Returns pow(10.0, (double)power), uses fast lookup table for exact powers */
      81        4411 : static inline double php_intpow10(int power) {
      82             :         static const double powers[] = {
      83             :                 1e0,  1e1,  1e2,  1e3,  1e4,  1e5,  1e6,  1e7,
      84             :                 1e8,  1e9,  1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
      85             :                 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
      86             : 
      87             :         /* Not in lookup table */
      88        4411 :         if (power < 0 || power > 22) {
      89          21 :                 return pow(10.0, (double)power);
      90             :         }
      91        4390 :         return powers[power];
      92             : }
      93             : /* }}} */
      94             : 
      95             : /* {{{ php_math_is_finite */
      96        1509 : static inline int php_math_is_finite(double value) {
      97             : #if defined(PHP_WIN32)
      98             :         return _finite(value);
      99             : #elif defined(isfinite)
     100        1509 :         return isfinite(value);
     101             : #else
     102             :         return value == value && (value == 0. || value * 2. != value);
     103             : #endif
     104             : }
     105             : /* }}} */
     106             : 
     107             : /* {{{ php_round_helper
     108             :        Actually performs the rounding of a value to integer in a certain mode */
     109        2932 : static inline double php_round_helper(double value, int mode) {
     110             :         double tmp_value;
     111             : 
     112        2932 :         if (value >= 0.0) {
     113        2868 :                 tmp_value = floor(value + 0.5);
     114        2876 :                 if ((mode == PHP_ROUND_HALF_DOWN && value == (-0.5 + tmp_value)) ||
     115           4 :                         (mode == PHP_ROUND_HALF_EVEN && value == (0.5 + 2 * floor(tmp_value/2.0))) ||
     116           4 :                         (mode == PHP_ROUND_HALF_ODD  && value == (0.5 + 2 * floor(tmp_value/2.0) - 1.0)))
     117             :                 {
     118           4 :                         tmp_value = tmp_value - 1.0;
     119             :                 }
     120             :         } else {
     121          64 :                 tmp_value = ceil(value - 0.5);
     122          72 :                 if ((mode == PHP_ROUND_HALF_DOWN && value == (0.5 + tmp_value)) ||
     123           4 :                         (mode == PHP_ROUND_HALF_EVEN && value == (-0.5 + 2 * ceil(tmp_value/2.0))) ||
     124           4 :                         (mode == PHP_ROUND_HALF_ODD  && value == (-0.5 + 2 * ceil(tmp_value/2.0) + 1.0)))
     125             :                 {
     126           4 :                         tmp_value = tmp_value + 1.0;
     127             :                 }
     128             :         }
     129             : 
     130        2932 :         return tmp_value;
     131             : }
     132             : /* }}} */
     133             : 
     134             : /* {{{ _php_math_round */
     135             : /*
     136             :  * Rounds a number to a certain number of decimal places in a certain rounding
     137             :  * mode. For the specifics of the algorithm, see http://wiki.php.net/rfc/rounding
     138             :  */
     139        1509 : PHPAPI double _php_math_round(double value, int places, int mode) {
     140             :         double f1, f2;
     141             :         double tmp_value;
     142             :         int precision_places;
     143             : 
     144        1509 :         if (!php_math_is_finite(value)) {
     145           2 :                 return value;
     146             :         }
     147             :         
     148        1507 :         precision_places = 14 - php_intlog10abs(value);
     149             : 
     150        1507 :         f1 = php_intpow10(abs(places));
     151             : 
     152             :         /* If the decimal precision guaranteed by FP arithmetic is higher than
     153             :            the requested places BUT is small enough to make sure a non-zero value
     154             :            is returned, pre-round the result to the precision */
     155        2959 :         if (precision_places > places && precision_places - places < 15) {
     156        1452 :                 f2 = php_intpow10(abs(precision_places));
     157        1452 :                 if (precision_places >= 0) {
     158        1446 :                         tmp_value = value * f2;
     159             :                 } else {
     160           6 :                         tmp_value = value / f2;
     161             :                 }
     162             :                 /* preround the result (tmp_value will always be something * 1e14,
     163             :                    thus never larger than 1e15 here) */
     164        1452 :                 tmp_value = php_round_helper(tmp_value, mode);
     165             :                 /* now correctly move the decimal point */
     166        1452 :                 f2 = php_intpow10(abs(places - precision_places));
     167             :                 /* because places < precision_places */
     168        1452 :                 tmp_value = tmp_value / f2;
     169             :         } else {
     170             :                 /* adjust the value */
     171          55 :                 if (places >= 0) {
     172          53 :                         tmp_value = value * f1;
     173             :                 } else {
     174           2 :                         tmp_value = value / f1;
     175             :                 }
     176             :                 /* This value is beyond our precision, so rounding it is pointless */
     177          55 :                 if (fabs(tmp_value) >= 1e15) {
     178          27 :                         return value;
     179             :                 }
     180             :         }
     181             : 
     182             :         /* round the temp value */
     183        1480 :         tmp_value = php_round_helper(tmp_value, mode);
     184             :         
     185             :         /* see if it makes sense to use simple division to round the value */
     186        2951 :         if (abs(places) < 23) {
     187        1471 :                 if (places > 0) {
     188         206 :                         tmp_value = tmp_value / f1;
     189             :                 } else {
     190        1265 :                         tmp_value = tmp_value * f1;
     191             :                 }
     192             :         } else {
     193             :                 /* Simple division can't be used since that will cause wrong results.
     194             :                    Instead, the number is converted to a string and back again using
     195             :                    strtod(). strtod() will return the nearest possible FP value for
     196             :                    that string. */
     197             : 
     198             :                 /* 40 Bytes should be more than enough for this format string. The
     199             :                    float won't be larger than 1e15 anyway. But just in case, use
     200             :                    snprintf() and make sure the buffer is zero-terminated */
     201             :                 char buf[40];
     202           9 :                 snprintf(buf, 39, "%15fe%d", tmp_value, -places);
     203           9 :                 buf[39] = '\0';
     204           9 :                 tmp_value = zend_strtod(buf, NULL);
     205             :                 /* couldn't convert to string and back */
     206           9 :                 if (!zend_finite(tmp_value) || zend_isnan(tmp_value)) {
     207           0 :                         tmp_value = value;
     208             :                 }
     209             :         }
     210             : 
     211        1480 :         return tmp_value;
     212             : }
     213             : /* }}} */
     214             : 
     215             : /* {{{ php_asinh
     216             : */
     217          33 : static double php_asinh(double z)
     218             : {
     219             : #ifdef HAVE_ASINH
     220          33 :         return(asinh(z));
     221             : #else
     222             :         return(log(z + sqrt(1 + pow(z, 2))) / log(M_E));
     223             : #endif
     224             : }
     225             : /* }}} */
     226             : 
     227             : /* {{{ php_acosh
     228             : */
     229          33 : static double php_acosh(double x)
     230             : {
     231             : #ifdef HAVE_ACOSH
     232          33 :         return(acosh(x));
     233             : #else
     234             :         return(log(x + sqrt(x * x - 1)));
     235             : #endif
     236             : }
     237             : /* }}} */
     238             : 
     239             : /* {{{ php_atanh
     240             : */
     241          33 : static double php_atanh(double z)
     242             : {
     243             : #ifdef HAVE_ATANH
     244          33 :         return(atanh(z));
     245             : #else
     246             :         return(0.5 * log((1 + z) / (1 - z)));
     247             : #endif
     248             : }
     249             : /* }}} */
     250             : 
     251             : /* {{{ php_log1p
     252             : */
     253          46 : static double php_log1p(double x)
     254             : {
     255             : #ifdef HAVE_LOG1P
     256          46 :         return(log1p(x));
     257             : #else
     258             :         return(log(1 + x));
     259             : #endif
     260             : }
     261             : /* }}} */
     262             : 
     263             : /* {{{ php_expm1
     264             : */
     265          45 : static double php_expm1(double x)
     266             : {
     267             : #if !defined(PHP_WIN32) && !defined(NETWARE)
     268          45 :         return(expm1(x));
     269             : #else
     270             :         return(exp(x) - 1);
     271             : #endif
     272             : }
     273             : /* }}}*/
     274             : 
     275             : /* {{{ proto int abs(int number)
     276             :    Return the absolute value of the number */
     277         282 : PHP_FUNCTION(abs) 
     278             : {
     279             :         zval **value;
     280             :         
     281         282 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &value) == FAILURE) {
     282           2 :                 return;
     283             :         }
     284         402 :         convert_scalar_to_number_ex(value);
     285             :         
     286         280 :         if (Z_TYPE_PP(value) == IS_DOUBLE) {
     287         213 :                 RETURN_DOUBLE(fabs(Z_DVAL_PP(value)));
     288          67 :         } else if (Z_TYPE_PP(value) == IS_LONG) {
     289          66 :                 if (Z_LVAL_PP(value) == LONG_MIN) {
     290           2 :                         RETURN_DOUBLE(-(double)LONG_MIN);
     291             :                 } else {
     292          64 :                         RETURN_LONG(Z_LVAL_PP(value) < 0 ? -Z_LVAL_PP(value) : Z_LVAL_PP(value));
     293             :                 }
     294             :         }
     295           1 :         RETURN_FALSE;
     296             : }
     297             : /* }}} */ 
     298             : 
     299             : /* {{{ proto float ceil(float number)
     300             :    Returns the next highest integer value of the number */
     301          71 : PHP_FUNCTION(ceil) 
     302             : {
     303             :         zval **value;
     304             :         
     305          71 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &value) == FAILURE) {
     306           2 :                 return;
     307             :         }
     308         190 :         convert_scalar_to_number_ex(value);
     309             : 
     310          69 :         if (Z_TYPE_PP(value) == IS_DOUBLE) {
     311          25 :                 RETURN_DOUBLE(ceil(Z_DVAL_PP(value)));
     312          44 :         } else if (Z_TYPE_PP(value) == IS_LONG) {
     313         210 :                 convert_to_double_ex(value);
     314          43 :                 RETURN_DOUBLE(Z_DVAL_PP(value));
     315             :         }
     316           1 :         RETURN_FALSE;
     317             : }
     318             : /* }}} */
     319             : 
     320             : /* {{{ proto float floor(float number)
     321             :    Returns the next lowest integer value from the number */
     322         435 : PHP_FUNCTION(floor)
     323             : {
     324             :         zval **value;
     325             :         
     326         435 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &value) == FAILURE) {
     327           2 :                 return;
     328             :         }
     329         554 :         convert_scalar_to_number_ex(value);
     330             : 
     331         433 :         if (Z_TYPE_PP(value) == IS_DOUBLE) {
     332         386 :                 RETURN_DOUBLE(floor(Z_DVAL_PP(value)));
     333          47 :         } else if (Z_TYPE_PP(value) == IS_LONG) {
     334         222 :                 convert_to_double_ex(value);
     335          46 :                 RETURN_DOUBLE(Z_DVAL_PP(value));
     336             :         }
     337           1 :         RETURN_FALSE;
     338             : }
     339             : /* }}} */
     340             : 
     341             : /* {{{ proto float round(float number [, int precision [, int mode]])
     342             :    Returns the number rounded to specified precision */
     343        1457 : PHP_FUNCTION(round)
     344             : {
     345             :         zval **value;
     346        1457 :         int places = 0;
     347        1457 :         long precision = 0;
     348        1457 :         long mode = PHP_ROUND_HALF_UP;
     349             :         double return_val;
     350             :         
     351        1457 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|ll", &value, &precision, &mode) == FAILURE) {
     352           9 :                 return;
     353             :         }
     354             : 
     355        1448 :         if (ZEND_NUM_ARGS() >= 2) {
     356         225 :                 places = (int) precision;
     357             :         }
     358        1719 :         convert_scalar_to_number_ex(value);
     359             : 
     360        1448 :         switch (Z_TYPE_PP(value)) {
     361             :                 case IS_LONG:
     362             :                         /* Simple case - long that doesn't need to be rounded. */
     363        1292 :                         if (places >= 0) {
     364        1292 :                                 RETURN_DOUBLE((double) Z_LVAL_PP(value));
     365             :                         }
     366             :                         /* break omitted intentionally */
     367             : 
     368             :                 case IS_DOUBLE:
     369         155 :                         return_val = (Z_TYPE_PP(value) == IS_LONG) ? (double)Z_LVAL_PP(value) : Z_DVAL_PP(value);
     370         155 :                         return_val = _php_math_round(return_val, places, mode);
     371         155 :                         RETURN_DOUBLE(return_val);
     372             :                         break;
     373             : 
     374             :                 default:
     375           1 :                         RETURN_FALSE;
     376             :                         break;
     377             :         }
     378             : }
     379             : /* }}} */
     380             : 
     381             : /* {{{ proto float sin(float number)
     382             :    Returns the sine of the number in radians */
     383          45 : PHP_FUNCTION(sin)
     384             : {
     385             :         double num;
     386             : 
     387          45 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     388           3 :                 return;
     389             :         }
     390          42 :         RETURN_DOUBLE(sin(num));
     391             : }
     392             : /* }}} */
     393             : 
     394             : /* {{{ proto float cos(float number)
     395             :    Returns the cosine of the number in radians */
     396          47 : PHP_FUNCTION(cos)
     397             : {
     398             :         double num;
     399             :         
     400          47 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     401           3 :                 return;
     402             :         }
     403          44 :         RETURN_DOUBLE(cos(num));
     404             : }
     405             : /* }}} */
     406             : 
     407             : /* {{{ proto float tan(float number)
     408             :    Returns the tangent of the number in radians */
     409          37 : PHP_FUNCTION(tan)
     410             : {
     411             :         double num;
     412             : 
     413          37 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     414           3 :                 return;
     415             :         }
     416          34 :         RETURN_DOUBLE(tan(num));
     417             : }
     418             : /* }}} */
     419             : 
     420             : /* {{{ proto float asin(float number)
     421             :    Returns the arc sine of the number in radians */
     422          36 : PHP_FUNCTION(asin)
     423             : {
     424             :         double num;
     425             : 
     426          36 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     427           3 :                 return;
     428             :         }
     429          33 :         RETURN_DOUBLE(asin(num));
     430             : }
     431             : /* }}} */
     432             : 
     433             : /* {{{ proto float acos(float number)
     434             :    Return the arc cosine of the number in radians */
     435          41 : PHP_FUNCTION(acos)
     436             : {
     437             :         double num;
     438             : 
     439          41 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     440           3 :                 return;
     441             :         }
     442          38 :         RETURN_DOUBLE(acos(num));
     443             : }
     444             : /* }}} */
     445             : 
     446             : /* {{{ proto float atan(float number)
     447             :    Returns the arc tangent of the number in radians */
     448          34 : PHP_FUNCTION(atan)
     449             : {
     450             :         double num;
     451             : 
     452          34 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     453           3 :                 return;
     454             :         }
     455          31 :         RETURN_DOUBLE(atan(num));
     456             : }
     457             : /* }}} */
     458             : 
     459             : /* {{{ proto float atan2(float y, float x)
     460             :    Returns the arc tangent of y/x, with the resulting quadrant determined by the signs of y and x */
     461         364 : PHP_FUNCTION(atan2)
     462             : {
     463             :         double num1, num2;
     464             : 
     465         364 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &num1, &num2) == FAILURE) {
     466          19 :                 return;
     467             :         }
     468         345 :         RETURN_DOUBLE(atan2(num1, num2));
     469             : }
     470             : /* }}} */
     471             : 
     472             : /* {{{ proto float sinh(float number)
     473             :    Returns the hyperbolic sine of the number, defined as (exp(number) - exp(-number))/2 */
     474          40 : PHP_FUNCTION(sinh)
     475             : {
     476             :         double num;
     477             : 
     478          40 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     479           3 :                 return;
     480             :         }
     481          37 :         RETURN_DOUBLE(sinh(num));
     482             : }
     483             : /* }}} */
     484             : 
     485             : /* {{{ proto float cosh(float number)
     486             :    Returns the hyperbolic cosine of the number, defined as (exp(number) + exp(-number))/2 */
     487          40 : PHP_FUNCTION(cosh)
     488             : {
     489             :         double num;
     490             : 
     491          40 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     492           3 :                 return;
     493             :         }
     494          37 :         RETURN_DOUBLE(cosh(num));
     495             : }
     496             : /* }}} */
     497             : 
     498             : /* {{{ proto float tanh(float number)
     499             :    Returns the hyperbolic tangent of the number, defined as sinh(number)/cosh(number) */
     500          40 : PHP_FUNCTION(tanh)
     501             : {
     502             :         double num;
     503             : 
     504          40 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     505           3 :                 return;
     506             :         }
     507          37 :         RETURN_DOUBLE(tanh(num));
     508             : }
     509             : /* }}} */
     510             : 
     511             : /* {{{ proto float asinh(float number)
     512             :    Returns the inverse hyperbolic sine of the number, i.e. the value whose hyperbolic sine is number */
     513          36 : PHP_FUNCTION(asinh)
     514             : {
     515             :         double num;
     516             : 
     517          36 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     518           3 :                 return;
     519             :         }
     520          33 :         RETURN_DOUBLE(php_asinh(num));
     521             : }
     522             : /* }}} */
     523             : 
     524             : /* {{{ proto float acosh(float number)
     525             :    Returns the inverse hyperbolic cosine of the number, i.e. the value whose hyperbolic cosine is number */
     526          36 : PHP_FUNCTION(acosh)
     527             : {
     528             :         double num;
     529             :         
     530          36 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     531           3 :                 return;
     532             :         }
     533          33 :         RETURN_DOUBLE(php_acosh(num));
     534             : }
     535             : /* }}} */
     536             : 
     537             : /* {{{ proto float atanh(float number)
     538             :    Returns the inverse hyperbolic tangent of the number, i.e. the value whose hyperbolic tangent is number */
     539          36 : PHP_FUNCTION(atanh)
     540             : {
     541             :         double num;
     542             : 
     543          36 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     544           3 :                 return;
     545             :         }
     546          33 :         RETURN_DOUBLE(php_atanh(num));
     547             : }
     548             : /* }}} */
     549             : 
     550             : /* {{{ proto float pi(void)
     551             :    Returns an approximation of pi */
     552           1 : PHP_FUNCTION(pi)
     553             : {
     554           1 :         RETURN_DOUBLE(M_PI);
     555             : }
     556             : /* }}} */
     557             : 
     558             : /* {{{ proto bool is_finite(float val)
     559             :    Returns whether argument is finite */
     560          58 : PHP_FUNCTION(is_finite)
     561             : {
     562             :         double dval;
     563             : 
     564          58 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &dval) == FAILURE) {
     565          10 :                 return;
     566             :         }
     567          48 :         RETURN_BOOL(zend_finite(dval));
     568             : }
     569             : /* }}} */
     570             : 
     571             : /* {{{ proto bool is_infinite(float val)
     572             :    Returns whether argument is infinite */
     573          66 : PHP_FUNCTION(is_infinite)
     574             : {
     575             :         double dval;
     576             : 
     577          66 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &dval) == FAILURE) {
     578          10 :                 return;
     579             :         }
     580          56 :         RETURN_BOOL(zend_isinf(dval));
     581             : }
     582             : /* }}} */
     583             : 
     584             : /* {{{ proto bool is_nan(float val)
     585             :    Returns whether argument is not a number */
     586          60 : PHP_FUNCTION(is_nan)
     587             : {
     588             :         double dval;
     589             : 
     590          60 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &dval) == FAILURE) {
     591          10 :                 return;
     592             :         }
     593          50 :         RETURN_BOOL(zend_isnan(dval));
     594             : }
     595             : /* }}} */
     596             : 
     597             : /* {{{ proto number pow(number base, number exponent)
     598             :    Returns base raised to the power of exponent. Returns integer result when possible */
     599        2222 : PHP_FUNCTION(pow)
     600             : {
     601             :         zval *zbase, *zexp;
     602             : 
     603        2222 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/z/", &zbase, &zexp) == FAILURE) {
     604           6 :                 return;
     605             :         }
     606             : 
     607        2216 :         pow_function(return_value, zbase, zexp TSRMLS_CC);
     608             : }
     609             : /* }}} */
     610             : 
     611             : /* {{{ proto float exp(float number)
     612             :    Returns e raised to the power of the number */
     613         256 : PHP_FUNCTION(exp)
     614             : {
     615             :         double num;
     616             : 
     617         256 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     618          10 :                 return;
     619             :         }
     620             : 
     621         246 :         RETURN_DOUBLE(exp(num));
     622             : }
     623             : /* }}} */
     624             : 
     625             : /* {{{ proto float expm1(float number)
     626             :    Returns exp(number) - 1, computed in a way that accurate even when the value of number is close to zero */
     627             : /*
     628             :    WARNING: this function is expermental: it could change its name or 
     629             :    disappear in the next version of PHP!
     630             : */
     631          59 : PHP_FUNCTION(expm1)
     632             : {
     633             :         double num;
     634             : 
     635          59 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     636          14 :                 return;
     637             :         }
     638          45 :         RETURN_DOUBLE(php_expm1(num));
     639             : }
     640             : /* }}} */
     641             : 
     642             : /* {{{ proto float log1p(float number)
     643             :    Returns log(1 + number), computed in a way that accurate even when the value of number is close to zero */ 
     644             : /*
     645             :    WARNING: this function is expermental: it could change its name or 
     646             :    disappear in the next version of PHP!
     647             : */
     648          56 : PHP_FUNCTION(log1p)
     649             : {
     650             :         double num;
     651             : 
     652          56 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     653          10 :                 return;
     654             :         }
     655          46 :         RETURN_DOUBLE(php_log1p(num));
     656             : }
     657             : /* }}} */
     658             : 
     659             : /* {{{ proto float log(float number, [float base])
     660             :    Returns the natural logarithm of the number, or the base log if base is specified */
     661         748 : PHP_FUNCTION(log)
     662             : {
     663         748 :         double num, base = 0;
     664             :         
     665         748 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|d", &num, &base) == FAILURE) {
     666          18 :                 return;
     667             :         }
     668         730 :         if (ZEND_NUM_ARGS() == 1) {
     669         231 :                 RETURN_DOUBLE(log(num));
     670             :         }
     671         499 :         if (base <= 0.0) {
     672          10 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "base must be greater than 0");                           
     673          10 :                 RETURN_FALSE;
     674             :         }
     675         489 :         if (base == 1) {
     676           3 :                 RETURN_DOUBLE(php_get_nan());
     677             :         } else {
     678         486 :                 RETURN_DOUBLE(log(num) / log(base));
     679             :         }
     680             : }
     681             : /* }}} */
     682             : 
     683             : /* {{{ proto float log10(float number)
     684             :    Returns the base-10 logarithm of the number */
     685          39 : PHP_FUNCTION(log10)
     686             : {
     687             :         double num;
     688             : 
     689          39 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     690           3 :                 return;
     691             :         }
     692          36 :         RETURN_DOUBLE(log10(num));
     693             : }
     694             : /* }}} */
     695             : 
     696             : /* {{{ proto float sqrt(float number)
     697             :    Returns the square root of the number */
     698          37 : PHP_FUNCTION(sqrt)
     699             : {
     700             :         double num;
     701             : 
     702          37 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
     703           3 :                 return;
     704             :         }
     705          34 :         RETURN_DOUBLE(sqrt(num));
     706             : }
     707             : /* }}} */
     708             : 
     709             : /* {{{ proto float hypot(float num1, float num2)
     710             :    Returns sqrt(num1*num1 + num2*num2) */ 
     711         389 : PHP_FUNCTION(hypot)
     712             : {
     713             :         double num1, num2;
     714             : 
     715         389 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &num1, &num2) == FAILURE) {
     716          19 :                 return;
     717             :         }
     718             : #if HAVE_HYPOT
     719         370 :         RETURN_DOUBLE(hypot(num1, num2));
     720             : #elif defined(_MSC_VER)
     721             :         RETURN_DOUBLE(_hypot(num1, num2));
     722             : #else
     723             :         RETURN_DOUBLE(sqrt((num1 * num1) + (num2 * num2)));
     724             : #endif
     725             : }
     726             : /* }}} */
     727             : 
     728             : /* {{{ proto float deg2rad(float number)
     729             :    Converts the number in degrees to the radian equivalent */
     730          39 : PHP_FUNCTION(deg2rad)
     731             : {
     732             :         double deg;
     733             : 
     734          39 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &deg) == FAILURE) {
     735           3 :                 return;
     736             :         }
     737          36 :         RETURN_DOUBLE((deg / 180.0) * M_PI);
     738             : }
     739             : /* }}} */
     740             : 
     741             : /* {{{ proto float rad2deg(float number)
     742             :    Converts the radian number to the equivalent number in degrees */
     743          36 : PHP_FUNCTION(rad2deg)
     744             : {
     745             :         double rad;
     746             : 
     747          36 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &rad) == FAILURE) {
     748           3 :                 return;
     749             :         }
     750          33 :         RETURN_DOUBLE((rad / M_PI) * 180);
     751             : }
     752             : /* }}} */
     753             : 
     754             : /* {{{ _php_math_basetolong */
     755             : /*
     756             :  * Convert a string representation of a base(2-36) number to a long.
     757             :  */
     758           0 : PHPAPI long _php_math_basetolong(zval *arg, int base)
     759             : {
     760           0 :         long num = 0, digit, onum;
     761             :         int i;
     762             :         char c, *s;
     763             : 
     764           0 :         if (Z_TYPE_P(arg) != IS_STRING || base < 2 || base > 36) {
     765           0 :                 return 0;
     766             :         }
     767             : 
     768           0 :         s = Z_STRVAL_P(arg);
     769             : 
     770           0 :         for (i = Z_STRLEN_P(arg); i > 0; i--) {
     771           0 :                 c = *s++;
     772             :                 
     773           0 :                 digit = (c >= '0' && c <= '9') ? c - '0'
     774           0 :                         : (c >= 'A' && c <= 'Z') ? c - 'A' + 10
     775           0 :                         : (c >= 'a' && c <= 'z') ? c - 'a' + 10
     776             :                         : base;
     777             :                 
     778           0 :                 if (digit >= base) {
     779           0 :                         continue;
     780             :                 }
     781             : 
     782           0 :                 onum = num;
     783           0 :                 num = num * base + digit;
     784           0 :                 if (num > onum)
     785           0 :                         continue;
     786             : 
     787             :                 {
     788             :                         TSRMLS_FETCH();
     789             : 
     790           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number '%s' is too big to fit in long", s);
     791           0 :                         return LONG_MAX;
     792             :                 }
     793             :         }
     794             : 
     795           0 :         return num;
     796             : }
     797             : /* }}} */
     798             : 
     799             : /* {{{ _php_math_basetozval */
     800             : /*
     801             :  * Convert a string representation of a base(2-36) number to a zval.
     802             :  */
     803         438 : PHPAPI int _php_math_basetozval(zval *arg, int base, zval *ret)
     804             : {
     805         438 :         long num = 0;
     806         438 :         double fnum = 0;
     807             :         int i;
     808         438 :         int mode = 0;
     809             :         char c, *s;
     810             :         long cutoff;
     811             :         int cutlim;
     812             : 
     813         438 :         if (Z_TYPE_P(arg) != IS_STRING || base < 2 || base > 36) {
     814           0 :                 return FAILURE;
     815             :         }
     816             : 
     817         438 :         s = Z_STRVAL_P(arg);
     818             : 
     819         438 :         cutoff = LONG_MAX / base;
     820         438 :         cutlim = LONG_MAX % base;
     821             :         
     822        2444 :         for (i = Z_STRLEN_P(arg); i > 0; i--) {
     823        2006 :                 c = *s++;
     824             : 
     825             :                 /* might not work for EBCDIC */
     826        3580 :                 if (c >= '0' && c <= '9') 
     827        1574 :                         c -= '0';
     828         564 :                 else if (c >= 'A' && c <= 'Z') 
     829         132 :                         c -= 'A' - 10;
     830         546 :                 else if (c >= 'a' && c <= 'z') 
     831         246 :                         c -= 'a' - 10;
     832             :                 else
     833          54 :                         continue;
     834             : 
     835        1952 :                 if (c >= base)
     836         368 :                         continue;
     837             :                 
     838        1584 :                 switch (mode) {
     839             :                 case 0: /* Integer */
     840        1575 :                         if (num < cutoff || (num == cutoff && c <= cutlim)) {
     841        1566 :                                 num = num * base + c;
     842        1566 :                                 break;
     843             :                         } else {
     844           9 :                                 fnum = num;
     845           9 :                                 mode = 1;
     846             :                         }
     847             :                         /* fall-through */
     848             :                 case 1: /* Float */
     849          18 :                         fnum = fnum * base + c;
     850             :                 }       
     851             :         }
     852             : 
     853         438 :         if (mode == 1) {
     854           9 :                 ZVAL_DOUBLE(ret, fnum);
     855             :         } else {
     856         429 :                 ZVAL_LONG(ret, num);
     857             :         }
     858         438 :         return SUCCESS;
     859             : }
     860             : /* }}} */
     861             : 
     862             : /* {{{ _php_math_longtobase */
     863             : /*
     864             :  * Convert a long to a string containing a base(2-36) representation of
     865             :  * the number.
     866             :  */
     867       36072 : PHPAPI char * _php_math_longtobase(zval *arg, int base)
     868             : {
     869             :         static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
     870             :         char buf[(sizeof(unsigned long) << 3) + 1];
     871             :         char *ptr, *end;
     872             :         unsigned long value;
     873             : 
     874       36072 :         if (Z_TYPE_P(arg) != IS_LONG || base < 2 || base > 36) {
     875           0 :                 return STR_EMPTY_ALLOC();
     876             :         }
     877             : 
     878       36072 :         value = Z_LVAL_P(arg);
     879             : 
     880       36072 :         end = ptr = buf + sizeof(buf) - 1;
     881       36072 :         *ptr = '\0';
     882             : 
     883             :         do {
     884      155343 :                 *--ptr = digits[value % base];
     885      155343 :                 value /= base;
     886      155343 :         } while (ptr > buf && value);
     887             : 
     888       36072 :         return estrndup(ptr, end - ptr);
     889             : }
     890             : /* }}} */
     891             : 
     892             : /* {{{ _php_math_zvaltobase */
     893             : /*
     894             :  * Convert a zval to a string containing a base(2-36) representation of
     895             :  * the number.
     896             :  */
     897         277 : PHPAPI char * _php_math_zvaltobase(zval *arg, int base TSRMLS_DC)
     898             : {
     899             :         static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
     900             : 
     901         277 :         if ((Z_TYPE_P(arg) != IS_LONG && Z_TYPE_P(arg) != IS_DOUBLE) || base < 2 || base > 36) {
     902           0 :                 return STR_EMPTY_ALLOC();
     903             :         }
     904             : 
     905         277 :         if (Z_TYPE_P(arg) == IS_DOUBLE) {
     906           0 :                 double fvalue = floor(Z_DVAL_P(arg)); /* floor it just in case */
     907             :                 char *ptr, *end;
     908             :                 char buf[(sizeof(double) << 3) + 1];
     909             : 
     910             :                 /* Don't try to convert +/- infinity */
     911           0 :                 if (fvalue == HUGE_VAL || fvalue == -HUGE_VAL) {
     912           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number too large");
     913           0 :                         return STR_EMPTY_ALLOC();
     914             :                 }
     915             : 
     916           0 :                 end = ptr = buf + sizeof(buf) - 1;
     917           0 :                 *ptr = '\0';
     918             : 
     919             :                 do {
     920           0 :                         *--ptr = digits[(int) fmod(fvalue, base)];
     921           0 :                         fvalue /= base;
     922           0 :                 } while (ptr > buf && fabs(fvalue) >= 1);
     923             : 
     924           0 :                 return estrndup(ptr, end - ptr);
     925             :         }
     926             :         
     927         277 :         return _php_math_longtobase(arg, base);
     928             : }       
     929             : /* }}} */
     930             : 
     931             : /* {{{ proto int bindec(string binary_number)
     932             :    Returns the decimal equivalent of the binary number */
     933          54 : PHP_FUNCTION(bindec)
     934             : {
     935             :         zval **arg;
     936             :         
     937          54 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
     938           2 :                 return;
     939             :         }
     940         211 :         convert_to_string_ex(arg);
     941          51 :         if (_php_math_basetozval(*arg, 2, return_value) == FAILURE) {
     942           0 :                 RETURN_FALSE;
     943             :         }
     944             : }
     945             : /* }}} */
     946             : 
     947             : /* {{{ proto int hexdec(string hexadecimal_number)
     948             :    Returns the decimal equivalent of the hexadecimal number */
     949          62 : PHP_FUNCTION(hexdec)
     950             : {
     951             :         zval **arg;
     952             :         
     953          62 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
     954           2 :                 return;
     955             :         }
     956         219 :         convert_to_string_ex(arg);
     957          59 :         if (_php_math_basetozval(*arg, 16, return_value) == FAILURE) {
     958           0 :                 RETURN_FALSE;
     959             :         }
     960             : }
     961             : /* }}} */
     962             : 
     963             : /* {{{ proto int octdec(string octal_number)
     964             :    Returns the decimal equivalent of an octal string */
     965          54 : PHP_FUNCTION(octdec)
     966             : {
     967             :         zval **arg;
     968             :         
     969          54 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
     970           2 :                 return;
     971             :         }
     972         211 :         convert_to_string_ex(arg);
     973          51 :         if (_php_math_basetozval(*arg, 8, return_value) == FAILURE) {
     974           0 :                 RETURN_FALSE;
     975             :         }
     976             : }
     977             : /* }}} */
     978             : 
     979             : /* {{{ proto string decbin(int decimal_number)
     980             :    Returns a string containing a binary representation of the number */
     981        2581 : PHP_FUNCTION(decbin)
     982             : {
     983             :         zval **arg;
     984             :         char *result;
     985             : 
     986        2581 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
     987           0 :                 return;
     988             :         }
     989        2752 :         convert_to_long_ex(arg);
     990        2581 :         result = _php_math_longtobase(*arg, 2);
     991        2581 :         RETURN_STRING(result, 0);
     992             : }
     993             : /* }}} */
     994             : 
     995             : /* {{{ proto string decoct(int decimal_number)
     996             :    Returns a string containing an octal representation of the given number */
     997         319 : PHP_FUNCTION(decoct)
     998             : {
     999             :         zval **arg;
    1000             :         char *result;
    1001             : 
    1002         319 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
    1003           2 :                 return;
    1004             :         }
    1005         488 :         convert_to_long_ex(arg);
    1006         317 :         result = _php_math_longtobase(*arg, 8);
    1007         317 :         RETURN_STRING(result, 0);
    1008             : }
    1009             : /* }}} */
    1010             : 
    1011             : /* {{{ proto string dechex(int decimal_number)
    1012             :    Returns a string containing a hexadecimal representation of the given number */
    1013       32899 : PHP_FUNCTION(dechex)
    1014             : {
    1015             :         zval **arg;
    1016             :         char *result;
    1017             : 
    1018       32899 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
    1019           2 :                 return;
    1020             :         }
    1021       33068 :         convert_to_long_ex(arg);
    1022       32897 :         result = _php_math_longtobase(*arg, 16);
    1023       32897 :         RETURN_STRING(result, 0);
    1024             : }
    1025             : /* }}} */
    1026             : 
    1027             : /* {{{ proto string base_convert(string number, int frombase, int tobase)
    1028             :    Converts a number in a string from any base <= 36 to any base <= 36 */
    1029         329 : PHP_FUNCTION(base_convert)
    1030             : {
    1031             :         zval **number, temp;
    1032             :         long frombase, tobase;
    1033             :         char *result;
    1034             : 
    1035         329 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zll", &number, &frombase, &tobase) == FAILURE) {
    1036          15 :                 return;
    1037             :         }
    1038        1152 :         convert_to_string_ex(number);
    1039             :         
    1040         313 :         if (frombase < 2 || frombase > 36) {
    1041          18 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid `from base' (%ld)", frombase);
    1042          18 :                 RETURN_FALSE;
    1043             :         }
    1044         295 :         if (tobase < 2 || tobase > 36) {
    1045          18 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid `to base' (%ld)", tobase);
    1046          18 :                 RETURN_FALSE;
    1047             :         }
    1048             : 
    1049         277 :         if(_php_math_basetozval(*number, frombase, &temp) == FAILURE) {
    1050           0 :                 RETURN_FALSE;
    1051             :         }
    1052         277 :         result = _php_math_zvaltobase(&temp, tobase TSRMLS_CC);
    1053         277 :         RETVAL_STRING(result, 0);
    1054             : } 
    1055             : /* }}} */
    1056             : 
    1057             : /* {{{ _php_math_number_format 
    1058             : */
    1059          59 : PHPAPI char *_php_math_number_format(double d, int dec, char dec_point, char thousand_sep)
    1060             : {
    1061          59 :         return _php_math_number_format_ex(d, dec, &dec_point, 1, &thousand_sep, 1);
    1062             : }
    1063             : 
    1064        1354 : static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point,
    1065             :                 size_t dec_point_len, char *thousand_sep, size_t thousand_sep_len,
    1066             :                 int *result_len)
    1067             : {
    1068        1354 :         char *tmpbuf = NULL, *resbuf;
    1069             :         char *s, *t;  /* source, target */
    1070             :         char *dp;
    1071             :         int integral;
    1072        1354 :         int tmplen, reslen=0;
    1073        1354 :         int count=0;
    1074        1354 :         int is_negative=0;
    1075             : 
    1076        1354 :         if (d < 0) {
    1077         378 :                 is_negative = 1;
    1078         378 :                 d = -d;
    1079             :         }
    1080             : 
    1081        1354 :         dec = MAX(0, dec);
    1082        1354 :         d = _php_math_round(d, dec, PHP_ROUND_HALF_UP);
    1083             : 
    1084        1354 :         tmplen = spprintf(&tmpbuf, 0, "%.*F", dec, d);
    1085             : 
    1086        1354 :         if (tmpbuf == NULL || !isdigit((int)tmpbuf[0])) {
    1087           2 :                 if (result_len) {
    1088           2 :                         *result_len = tmplen;
    1089             :                 }
    1090             : 
    1091           2 :                 return tmpbuf;
    1092             :         }
    1093             : 
    1094             :         /* find decimal point, if expected */
    1095        1352 :         if (dec) {
    1096         125 :                 dp = strpbrk(tmpbuf, ".,");
    1097             :         } else {
    1098        1227 :                 dp = NULL;
    1099             :         }
    1100             : 
    1101             :         /* calculate the length of the return buffer */
    1102        1352 :         if (dp) {
    1103         125 :                 integral = dp - tmpbuf;
    1104             :         } else {
    1105             :                 /* no decimal point was found */
    1106        1227 :                 integral = tmplen;
    1107             :         }
    1108             : 
    1109             :         /* allow for thousand separators */
    1110        1352 :         if (thousand_sep) {
    1111        1352 :                 integral += thousand_sep_len * ((integral-1) / 3);
    1112             :         }
    1113             :         
    1114        1352 :         reslen = integral;
    1115             :         
    1116        1352 :         if (dec) {
    1117         125 :                 reslen += dec;
    1118             : 
    1119         125 :                 if (dec_point) {
    1120         125 :                         reslen += dec_point_len;
    1121             :                 }
    1122             :         }
    1123             : 
    1124             :         /* add a byte for minus sign */
    1125        1352 :         if (is_negative) {
    1126         378 :                 reslen++;
    1127             :         }
    1128        1352 :         resbuf = (char *) emalloc(reslen+1); /* +1 for NUL terminator */
    1129             : 
    1130        1352 :         s = tmpbuf+tmplen-1;
    1131        1352 :         t = resbuf+reslen;
    1132        1352 :         *t-- = '\0';
    1133             : 
    1134             :         /* copy the decimal places.
    1135             :          * Take care, as the sprintf implementation may return less places than
    1136             :          * we requested due to internal buffer limitations */
    1137        1352 :         if (dec) {
    1138         125 :                 int declen = dp ? s - dp : 0;
    1139         125 :                 int topad = dec > declen ? dec - declen : 0;
    1140             : 
    1141             :                 /* pad with '0's */
    1142        4388 :                 while (topad--) {
    1143        4138 :                         *t-- = '0';
    1144             :                 }
    1145             :                 
    1146         125 :                 if (dp) {
    1147         125 :                         s -= declen + 1; /* +1 to skip the point */
    1148         125 :                         t -= declen;
    1149             : 
    1150             :                         /* now copy the chars after the point */
    1151         125 :                         memcpy(t + 1, dp + 1, declen);
    1152             :                 }
    1153             : 
    1154             :                 /* add decimal point */
    1155         125 :                 if (dec_point) {
    1156         125 :                         t -= dec_point_len;
    1157         125 :                         memcpy(t + 1, dec_point, dec_point_len);
    1158             :                 }
    1159             :         }
    1160             : 
    1161             :         /* copy the numbers before the decimal point, adding thousand
    1162             :          * separator every three digits */
    1163        8554 :         while(s >= tmpbuf) {
    1164        5850 :                 *t-- = *s--;
    1165        5850 :                 if (thousand_sep && (++count%3)==0 && s>=tmpbuf) {
    1166        1089 :                         t -= thousand_sep_len;
    1167        1089 :                         memcpy(t + 1, thousand_sep, thousand_sep_len);
    1168             :                 }
    1169             :         }
    1170             : 
    1171             :         /* and a minus sign, if needed */
    1172        1352 :         if (is_negative) {
    1173         378 :                 *t-- = '-';
    1174             :         }
    1175             : 
    1176        1352 :         efree(tmpbuf);
    1177             :         
    1178        1352 :         if (result_len) {
    1179        1293 :                 *result_len = reslen;
    1180             :         }
    1181             : 
    1182        1352 :         return resbuf;
    1183             : }
    1184             : 
    1185          59 : PHPAPI char *_php_math_number_format_ex(double d, int dec, char *dec_point,
    1186             :                 size_t dec_point_len, char *thousand_sep, size_t thousand_sep_len)
    1187             : {
    1188          59 :         return _php_math_number_format_ex_len(d, dec, dec_point, dec_point_len,
    1189             :                         thousand_sep, thousand_sep_len, NULL);
    1190             : }
    1191             : /* }}} */
    1192             : 
    1193             : /* {{{ proto string number_format(float number [, int num_decimal_places [, string dec_separator, string thousands_separator]])
    1194             :    Formats a number with grouped thousands */
    1195        1357 : PHP_FUNCTION(number_format)
    1196             : {
    1197             :         double num;
    1198        1357 :         long dec = 0;
    1199        1357 :         char *thousand_sep = NULL, *dec_point = NULL;
    1200        1357 :         char thousand_sep_chr = ',', dec_point_chr = '.';
    1201        1357 :         int thousand_sep_len = 0, dec_point_len = 0;
    1202             :         
    1203        1357 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|ls!s!", &num, &dec, &dec_point, &dec_point_len, &thousand_sep, &thousand_sep_len) == FAILURE) {
    1204           2 :                 return;
    1205             :         }
    1206             : 
    1207        1355 :         switch(ZEND_NUM_ARGS()) {
    1208             :         case 1:
    1209          24 :                 RETURN_STRING(_php_math_number_format(num, 0, dec_point_chr, thousand_sep_chr), 0);
    1210             :                 break;
    1211             :         case 2:
    1212          35 :                 RETURN_STRING(_php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr), 0);
    1213             :                 break;
    1214             :         case 4:
    1215        1295 :                 if (dec_point == NULL) {
    1216           1 :                         dec_point = &dec_point_chr;
    1217           1 :                         dec_point_len = 1;
    1218             :                 }
    1219             : 
    1220        1295 :                 if (thousand_sep == NULL) {
    1221           0 :                         thousand_sep = &thousand_sep_chr;
    1222           0 :                         thousand_sep_len = 1;
    1223             :                 }
    1224             : 
    1225        1295 :                 Z_TYPE_P(return_value) = IS_STRING;
    1226        1295 :                 Z_STRVAL_P(return_value) = _php_math_number_format_ex_len(num, dec,
    1227             :                                 dec_point, dec_point_len, thousand_sep, thousand_sep_len,
    1228             :                                 &Z_STRLEN_P(return_value));
    1229        1295 :                 break;
    1230             :         default:
    1231           1 :                 WRONG_PARAM_COUNT;
    1232             :                 break;
    1233             :         }
    1234             : }
    1235             : /* }}} */
    1236             : 
    1237             : /* {{{ proto float fmod(float x, float y)
    1238             :    Returns the remainder of dividing x by y as a float */
    1239         364 : PHP_FUNCTION(fmod)
    1240             : {
    1241             :         double num1, num2;
    1242             : 
    1243         364 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd",  &num1, &num2) == FAILURE) {
    1244          19 :                 return;
    1245             :         }
    1246         345 :         RETURN_DOUBLE(fmod(num1, num2));
    1247             : }
    1248             : /* }}} */
    1249             : 
    1250             : 
    1251             : 
    1252             : /*
    1253             :  * Local variables:
    1254             :  * tab-width: 4
    1255             :  * c-basic-offset: 4
    1256             :  * End:
    1257             :  * vim600: fdm=marker
    1258             :  * vim: noet sw=4 ts=4
    1259             :  */

Generated by: LCOV version 1.10

Generated at Mon, 04 Aug 2014 15:49:13 +0000 (42 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.