LTP GCOV extension - code coverage report
Current view: directory - ext/standard - math.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 444
Code covered: 2.9 % Executed lines: 13
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2007 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: math.c,v 1.131.2.2.2.5 2007/01/01 09:36:08 sebastian Exp $ */
      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                 : #ifndef PHP_ROUND_FUZZ
      33                 : # ifndef PHP_WIN32
      34                 : #  define PHP_ROUND_FUZZ 0.50000000001
      35                 : # else
      36                 : #  define PHP_ROUND_FUZZ 0.5
      37                 : # endif
      38                 : #endif
      39                 : 
      40                 : #define PHP_ROUND_WITH_FUZZ(val, places) {                      \
      41                 :         double tmp_val=val, f = pow(10.0, (double) places);     \
      42                 :         tmp_val *= f;                                   \
      43                 :         if (tmp_val >= 0.0) {                                \
      44                 :                 tmp_val = floor(tmp_val + PHP_ROUND_FUZZ);      \
      45                 :         } else {                                        \
      46                 :                 tmp_val = ceil(tmp_val - PHP_ROUND_FUZZ);       \
      47                 :         }                                               \
      48                 :         tmp_val /= f;                                   \
      49                 :         val = !zend_isnan(tmp_val) ? tmp_val : val;     \
      50                 : }                                                       \
      51                 : 
      52                 : /* {{{ proto int abs(int number)
      53                 :    Return the absolute value of the number */
      54                 : PHP_FUNCTION(abs) 
      55               0 : {
      56                 :         zval **value;
      57                 :         
      58               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &value) == FAILURE) {
      59               0 :                 WRONG_PARAM_COUNT;
      60                 :         }
      61                 : 
      62               0 :         convert_scalar_to_number_ex(value);
      63                 :         
      64               0 :         if (Z_TYPE_PP(value) == IS_DOUBLE) {
      65               0 :                 RETURN_DOUBLE(fabs(Z_DVAL_PP(value)));
      66               0 :         } else if (Z_TYPE_PP(value) == IS_LONG) {
      67               0 :                 if (Z_LVAL_PP(value) == LONG_MIN) {
      68               0 :                         RETURN_DOUBLE(-(double)LONG_MIN);
      69                 :                 } else {
      70               0 :                         RETURN_LONG(Z_LVAL_PP(value) < 0 ? -Z_LVAL_PP(value) : Z_LVAL_PP(value));
      71                 :                 }
      72                 :         }
      73               0 :         RETURN_FALSE;
      74                 : }
      75                 : /* }}} */ 
      76                 : 
      77                 : /* {{{ proto float ceil(float number)
      78                 :    Returns the next highest integer value of the number */
      79                 : PHP_FUNCTION(ceil) 
      80               0 : {
      81                 :         zval **value;
      82                 :         
      83               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &value) == FAILURE) {
      84               0 :                 WRONG_PARAM_COUNT;
      85                 :         }
      86                 : 
      87               0 :         convert_scalar_to_number_ex(value);
      88                 : 
      89               0 :         if (Z_TYPE_PP(value) == IS_DOUBLE) {
      90               0 :                 RETURN_DOUBLE(ceil(Z_DVAL_PP(value)));
      91               0 :         } else if (Z_TYPE_PP(value) == IS_LONG) {
      92               0 :                 convert_to_double_ex(value);
      93               0 :                 RETURN_DOUBLE(Z_DVAL_PP(value));
      94                 :         }
      95                 : 
      96               0 :         RETURN_FALSE;
      97                 : }
      98                 : /* }}} */
      99                 : 
     100                 : /* {{{ proto float floor(float number)
     101                 :    Returns the next lowest integer value from the number */
     102                 : PHP_FUNCTION(floor)
     103               0 : {
     104                 :         zval **value;
     105                 :         
     106               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &value) == FAILURE) {
     107               0 :                 WRONG_PARAM_COUNT;
     108                 :         }
     109                 : 
     110               0 :         convert_scalar_to_number_ex(value);
     111                 : 
     112               0 :         if (Z_TYPE_PP(value) == IS_DOUBLE) {
     113               0 :                 RETURN_DOUBLE(floor(Z_DVAL_PP(value)));
     114               0 :         } else if (Z_TYPE_PP(value) == IS_LONG) {
     115               0 :                 convert_to_double_ex(value);
     116               0 :                 RETURN_DOUBLE(Z_DVAL_PP(value));
     117                 :         }
     118                 : 
     119               0 :         RETURN_FALSE;
     120                 : }
     121                 : /* }}} */
     122                 : 
     123                 : /* {{{ proto float round(float number [, int precision])
     124                 :    Returns the number rounded to specified precision */
     125                 : PHP_FUNCTION(round)
     126             108 : {
     127                 :         zval **value, **precision;
     128             108 :         int places = 0;
     129                 :         double return_val;
     130                 :         
     131             108 :         if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2 ||
     132                 :                 zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &precision) == FAILURE) {
     133               0 :                 WRONG_PARAM_COUNT;
     134                 :         }
     135                 : 
     136             108 :         if (ZEND_NUM_ARGS() == 2) {
     137             108 :                 convert_to_long_ex(precision);
     138             108 :                 places = (int) Z_LVAL_PP(precision);
     139                 :         }
     140                 : 
     141             108 :         convert_scalar_to_number_ex(value);
     142                 : 
     143             108 :         switch (Z_TYPE_PP(value)) {
     144                 :                 case IS_LONG:
     145                 :                         /* Simple case - long that doesn't need to be rounded. */
     146              26 :                         if (places >= 0) {
     147              26 :                                 RETURN_DOUBLE((double) Z_LVAL_PP(value));
     148                 :                         }
     149                 :                         /* break omitted intentionally */
     150                 : 
     151                 :                 case IS_DOUBLE:
     152              82 :                         return_val = (Z_TYPE_PP(value) == IS_LONG) ?
     153                 :                                                         (double)Z_LVAL_PP(value) : Z_DVAL_PP(value);
     154                 : 
     155              82 :                         PHP_ROUND_WITH_FUZZ(return_val, places);
     156                 : 
     157              82 :                         RETURN_DOUBLE(return_val);
     158                 :                         break;
     159                 : 
     160                 :                 default:
     161               0 :                         RETURN_FALSE;
     162                 :                         break;
     163                 :         }
     164                 : }
     165                 : /* }}} */
     166                 : 
     167                 : /* {{{ proto float sin(float number)
     168                 :    Returns the sine of the number in radians */
     169                 : PHP_FUNCTION(sin)
     170               0 : {
     171                 :         zval **num;
     172                 : 
     173               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     174               0 :                 WRONG_PARAM_COUNT;
     175                 :         }
     176               0 :         convert_to_double_ex(num);
     177               0 :         Z_DVAL_P(return_value) = sin(Z_DVAL_PP(num));
     178               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     179                 : }
     180                 : /* }}} */
     181                 : 
     182                 : /* {{{ proto float cos(float number)
     183                 :    Returns the cosine of the number in radians */
     184                 : PHP_FUNCTION(cos)
     185               0 : {
     186                 :         zval **num;
     187                 : 
     188               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     189               0 :                 WRONG_PARAM_COUNT;
     190                 :         }
     191               0 :         convert_to_double_ex(num);
     192               0 :         Z_DVAL_P(return_value) = cos(Z_DVAL_PP(num));
     193               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     194                 : }
     195                 : /* }}} */
     196                 : 
     197                 : /* {{{ proto float tan(float number)
     198                 :    Returns the tangent of the number in radians */
     199                 : PHP_FUNCTION(tan)
     200               0 : {
     201                 :         zval **num;
     202                 : 
     203               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     204               0 :                 WRONG_PARAM_COUNT;
     205                 :         }
     206               0 :         convert_to_double_ex(num);
     207               0 :         Z_DVAL_P(return_value) = tan(Z_DVAL_PP(num));
     208               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     209                 : }
     210                 : /* }}} */
     211                 : 
     212                 : /* {{{ proto float asin(float number)
     213                 :    Returns the arc sine of the number in radians */
     214                 : PHP_FUNCTION(asin)
     215               0 : {
     216                 :         zval **num;
     217                 : 
     218               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     219               0 :                 WRONG_PARAM_COUNT;
     220                 :         }
     221               0 :         convert_to_double_ex(num);
     222               0 :         Z_DVAL_P(return_value) = asin(Z_DVAL_PP(num));
     223               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     224                 : }
     225                 : /* }}} */
     226                 : 
     227                 : /* {{{ proto float acos(float number)
     228                 :    Return the arc cosine of the number in radians */
     229                 : PHP_FUNCTION(acos)
     230               0 : {
     231                 :         zval **num;
     232                 : 
     233               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     234               0 :                 WRONG_PARAM_COUNT;
     235                 :         }
     236               0 :         convert_to_double_ex(num);
     237               0 :         Z_DVAL_P(return_value) = acos(Z_DVAL_PP(num));
     238               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     239                 : }
     240                 : /* }}} */
     241                 : 
     242                 : /* {{{ proto float atan(float number)
     243                 :    Returns the arc tangent of the number in radians */
     244                 : PHP_FUNCTION(atan)
     245               0 : {
     246                 :         zval **num;
     247                 : 
     248               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     249               0 :                 WRONG_PARAM_COUNT;
     250                 :         }
     251               0 :         convert_to_double_ex(num);
     252               0 :         Z_DVAL_P(return_value) = atan(Z_DVAL_PP(num));
     253               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     254                 : }
     255                 : /* }}} */
     256                 : 
     257                 : /* {{{ proto float atan2(float y, float x)
     258                 :    Returns the arc tangent of y/x, with the resulting quadrant determined by the signs of y and x */
     259                 : PHP_FUNCTION(atan2)
     260               0 : {
     261                 :         zval **num1, **num2;
     262                 : 
     263               0 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &num1, &num2) == FAILURE) {
     264               0 :                 WRONG_PARAM_COUNT;
     265                 :         }
     266               0 :         convert_to_double_ex(num1);
     267               0 :         convert_to_double_ex(num2);
     268               0 :         Z_DVAL_P(return_value) = atan2(Z_DVAL_PP(num1), Z_DVAL_PP(num2));
     269               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     270                 : }
     271                 : /* }}} */
     272                 : 
     273                 : /* {{{ proto float sinh(float number)
     274                 :    Returns the hyperbolic sine of the number, defined as (exp(number) - exp(-number))/2 */
     275                 : PHP_FUNCTION(sinh)
     276               0 : {
     277                 :         zval **num;
     278                 : 
     279               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     280               0 :                 WRONG_PARAM_COUNT;
     281                 :         }
     282               0 :         convert_to_double_ex(num);
     283               0 :         Z_DVAL_P(return_value) = sinh(Z_DVAL_PP(num));
     284               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     285                 : }
     286                 : /* }}} */
     287                 : 
     288                 : /* {{{ proto float cosh(float number)
     289                 :    Returns the hyperbolic cosine of the number, defined as (exp(number) + exp(-number))/2 */
     290                 : PHP_FUNCTION(cosh)
     291               0 : {
     292                 :         zval **num;
     293                 : 
     294               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     295               0 :                 WRONG_PARAM_COUNT;
     296                 :         }
     297               0 :         convert_to_double_ex(num);
     298               0 :         Z_DVAL_P(return_value) = cosh(Z_DVAL_PP(num));
     299               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     300                 : }
     301                 : /* }}} */
     302                 : 
     303                 : /* {{{ proto float tanh(float number)
     304                 :    Returns the hyperbolic tangent of the number, defined as sinh(number)/cosh(number) */
     305                 : PHP_FUNCTION(tanh)
     306               0 : {
     307                 :         zval **num;
     308                 : 
     309               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     310               0 :                 WRONG_PARAM_COUNT;
     311                 :         }
     312               0 :         convert_to_double_ex(num);
     313               0 :         Z_DVAL_P(return_value) = tanh(Z_DVAL_PP(num));
     314               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     315                 : }
     316                 : /* }}} */
     317                 : 
     318                 : #if !defined(PHP_WIN32) && !defined(NETWARE)
     319                 : #ifdef HAVE_ASINH
     320                 : /* {{{ proto float asinh(float number)
     321                 :    Returns the inverse hyperbolic sine of the number, i.e. the value whose hyperbolic sine is number */
     322                 : PHP_FUNCTION(asinh)
     323               0 : {
     324                 :         zval **num;
     325                 : 
     326               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     327               0 :                 WRONG_PARAM_COUNT;
     328                 :         }
     329               0 :         convert_to_double_ex(num);
     330               0 :         Z_DVAL_P(return_value) = asinh(Z_DVAL_PP(num));
     331               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     332                 : }
     333                 : /* }}} */
     334                 : #endif /* HAVE_ASINH */
     335                 : 
     336                 : #ifdef HAVE_ACOSH
     337                 : /* {{{ proto float acosh(float number)
     338                 :    Returns the inverse hyperbolic cosine of the number, i.e. the value whose hyperbolic cosine is number */
     339                 : PHP_FUNCTION(acosh)
     340               0 : {
     341                 :         zval **num;
     342                 : 
     343               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     344               0 :                 WRONG_PARAM_COUNT;
     345                 :         }
     346               0 :         convert_to_double_ex(num);
     347               0 :         Z_DVAL_P(return_value) = acosh(Z_DVAL_PP(num));
     348               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     349                 : }
     350                 : /* }}} */
     351                 : #endif /* HAVE_ACOSH */
     352                 : 
     353                 : #ifdef HAVE_ATANH
     354                 : /* {{{ proto float atanh(float number)
     355                 :    Returns the inverse hyperbolic tangent of the number, i.e. the value whose hyperbolic tangent is number */
     356                 : PHP_FUNCTION(atanh)
     357               0 : {
     358                 :         zval **num;
     359                 : 
     360               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     361               0 :                 WRONG_PARAM_COUNT;
     362                 :         }
     363               0 :         convert_to_double_ex(num);
     364               0 :         Z_DVAL_P(return_value) = atanh(Z_DVAL_PP(num));
     365               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     366                 : }
     367                 : /* }}} */
     368                 : #endif /* HAVE_ATANH */
     369                 : #endif /* !defined(PHP_WIN32) && !defined(NETWARE) */
     370                 : 
     371                 : /* {{{ proto float pi(void)
     372                 :    Returns an approximation of pi */
     373                 : PHP_FUNCTION(pi)
     374               0 : {
     375               0 :         Z_DVAL_P(return_value) = M_PI;
     376               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     377               0 : }
     378                 : /* }}} */
     379                 : 
     380                 : /* {{{ proto bool is_finite(float val)
     381                 :    Returns whether argument is finite */
     382                 : PHP_FUNCTION(is_finite)
     383               0 : {
     384                 :         double dval;
     385                 : 
     386                 : 
     387               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &dval) == FAILURE) {
     388               0 :                 return;
     389                 :         }
     390               0 :         RETURN_BOOL(zend_finite(dval));
     391                 : }
     392                 : /* }}} */
     393                 : 
     394                 : /* {{{ proto bool is_infinite(float val)
     395                 :    Returns whether argument is infinite */
     396                 : PHP_FUNCTION(is_infinite)
     397               0 : {
     398                 :         double dval;
     399                 : 
     400               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &dval) == FAILURE) {
     401               0 :                 return;
     402                 :         }
     403               0 :         RETURN_BOOL(zend_isinf(dval));
     404                 : }
     405                 : /* }}} */
     406                 : 
     407                 : /* {{{ proto bool is_nan(float val)
     408                 :    Returns whether argument is not a number */
     409                 : PHP_FUNCTION(is_nan)
     410               0 : {
     411                 :         double dval;
     412                 : 
     413               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &dval) == FAILURE) {
     414               0 :                 return;
     415                 :         }
     416               0 :         RETURN_BOOL(zend_isnan(dval));
     417                 : }
     418                 : /* }}} */
     419                 : 
     420                 : /* {{{ proto number pow(number base, number exponent)
     421                 :    Returns base raised to the power of exponent. Returns integer result when possible */
     422                 : PHP_FUNCTION(pow)
     423               0 : {
     424                 :         zval *zbase, *zexp;
     425                 : 
     426               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/z/", &zbase, &zexp) == FAILURE) {
     427               0 :                 return;
     428                 :         }
     429                 : 
     430                 :         /* make sure we're dealing with numbers */
     431               0 :         convert_scalar_to_number(zbase TSRMLS_CC);
     432               0 :         convert_scalar_to_number(zexp TSRMLS_CC);
     433                 : 
     434                 :         /* if both base and exponent were longs, we'll try to get a long out */
     435               0 :         if (Z_TYPE_P(zbase) == IS_LONG && Z_TYPE_P(zexp) == IS_LONG && Z_LVAL_P(zexp) >= 0) {
     436               0 :                 long l1 = 1, l2 = Z_LVAL_P(zbase), i = Z_LVAL_P(zexp);
     437                 :                 
     438               0 :                 if (i == 0) {
     439               0 :                         RETURN_LONG(1L);
     440               0 :                 } else if (l2 == 0) {
     441               0 :                         RETURN_LONG(0);
     442                 :                 }
     443                 : 
     444                 :                 /* calculate pow(long,long) in O(log exp) operations, bail if overflow */
     445               0 :                 while (i >= 1) {
     446                 :                         int overflow;
     447               0 :                         double dval = 0.0;
     448                 : 
     449               0 :                         if (i % 2) {
     450               0 :                                 --i;
     451               0 :                                 ZEND_SIGNED_MULTIPLY_LONG(l1,l2,l1,dval,overflow);
     452               0 :                                 if (overflow) RETURN_DOUBLE(dval * pow(l2,i));
     453                 :                         } else {
     454               0 :                                 i /= 2;
     455               0 :                                 ZEND_SIGNED_MULTIPLY_LONG(l2,l2,l2,dval,overflow);
     456               0 :                                 if (overflow) RETURN_DOUBLE((double)l1 * pow(dval,i));
     457                 :                         }
     458               0 :                         if (i == 0) {
     459               0 :                                 RETURN_LONG(l1);
     460                 :                         }
     461                 :                 }
     462                 :         }
     463               0 :         convert_to_double(zbase);
     464               0 :         convert_to_double(zexp);
     465                 :         
     466               0 :         RETURN_DOUBLE( pow(Z_DVAL_P(zbase),Z_DVAL_P(zexp)) );
     467                 : }
     468                 : /* }}} */
     469                 : 
     470                 : /* {{{ proto float exp(float number)
     471                 :    Returns e raised to the power of the number */
     472                 : PHP_FUNCTION(exp)
     473               0 : {
     474                 :         zval **num;
     475                 : 
     476               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     477               0 :                 WRONG_PARAM_COUNT;
     478                 :         }
     479               0 :         convert_to_double_ex(num);
     480               0 :         Z_DVAL_P(return_value) = exp(Z_DVAL_PP(num));
     481               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     482                 : }
     483                 : /* }}} */
     484                 : 
     485                 : #if !defined(PHP_WIN32) && !defined(NETWARE)
     486                 : /* {{{ proto float expm1(float number)
     487                 :    Returns exp(number) - 1, computed in a way that accurate even when the value of number is close to zero */
     488                 : /*
     489                 :    WARNING: this function is expermental: it could change its name or 
     490                 :    disappear in the next version of PHP!
     491                 : */
     492                 : PHP_FUNCTION(expm1)
     493               0 : {
     494                 :         zval **num;
     495                 : 
     496               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     497               0 :                 WRONG_PARAM_COUNT;
     498                 :         }
     499               0 :         convert_to_double_ex(num);
     500               0 :         Z_DVAL_P(return_value) = expm1(Z_DVAL_PP(num));
     501               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     502                 : }
     503                 : /* }}} */
     504                 : 
     505                 : #ifdef HAVE_LOG1P
     506                 : /* {{{ proto float log1p(float number)
     507                 :    Returns log(1 + number), computed in a way that accurate even when the value of number is close to zero */ 
     508                 : /*
     509                 :    WARNING: this function is expermental: it could change its name or 
     510                 :    disappear in the next version of PHP!
     511                 : */
     512                 : PHP_FUNCTION(log1p)
     513               0 : {
     514                 :         zval **num;
     515                 : 
     516               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     517               0 :                 WRONG_PARAM_COUNT;
     518                 :         }
     519               0 :         convert_to_double_ex(num);
     520               0 :         Z_DVAL_P(return_value) = log1p(Z_DVAL_PP(num));
     521               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     522                 : }
     523                 : /* }}} */
     524                 : #endif /* HAVE_LOG1P */
     525                 : #endif /* !defined(PHP_WIN32) && !defined(NETWARE) */
     526                 : 
     527                 : /* {{{ proto float log(float number, [float base])
     528                 :    Returns the natural logarithm of the number, or the base log if base is specified */
     529                 : PHP_FUNCTION(log)
     530               0 : {
     531                 :         zval **num, **base;
     532                 :         
     533               0 :         switch (ZEND_NUM_ARGS()) {
     534                 :                 case 1:
     535               0 :                         if (zend_get_parameters_ex(1, &num) == FAILURE) {
     536               0 :                                 WRONG_PARAM_COUNT;
     537                 :                         }
     538               0 :                         convert_to_double_ex(num);
     539               0 :                         RETURN_DOUBLE(log(Z_DVAL_PP(num)));
     540                 :                 case 2:
     541               0 :                         if (zend_get_parameters_ex(2, &num, &base) == FAILURE) {
     542               0 :                                 WRONG_PARAM_COUNT;
     543                 :                         }
     544               0 :                         convert_to_double_ex(num);
     545               0 :                         convert_to_double_ex(base);
     546                 :                 
     547               0 :                         if (Z_DVAL_PP(base) <= 0.0) {
     548               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "base must be greater than 0");                           
     549               0 :                                 RETURN_FALSE;
     550                 :                         }
     551               0 :                         RETURN_DOUBLE(log(Z_DVAL_PP(num)) / log(Z_DVAL_PP(base)));
     552                 :                 default:
     553               0 :                         WRONG_PARAM_COUNT;
     554                 :         }
     555                 : }
     556                 : /* }}} */
     557                 : 
     558                 : /* {{{ proto float log10(float number)
     559                 :    Returns the base-10 logarithm of the number */
     560                 : PHP_FUNCTION(log10)
     561               0 : {
     562                 :         zval **num;
     563                 : 
     564               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     565               0 :                 WRONG_PARAM_COUNT;
     566                 :         }
     567               0 :         convert_to_double_ex(num);
     568               0 :         Z_DVAL_P(return_value) = log10(Z_DVAL_PP(num));
     569               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     570                 : }
     571                 : /* }}} */
     572                 : 
     573                 : /* {{{ proto float sqrt(float number)
     574                 :    Returns the square root of the number */
     575                 : PHP_FUNCTION(sqrt)
     576               0 : {
     577                 :         zval **num;
     578                 : 
     579               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
     580               0 :                 WRONG_PARAM_COUNT;
     581                 :         }
     582               0 :         convert_to_double_ex(num);
     583               0 :         Z_DVAL_P(return_value) = sqrt(Z_DVAL_PP(num));
     584               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     585                 : }
     586                 : /* }}} */
     587                 : 
     588                 : /* {{{ proto float hypot(float num1, float num2)
     589                 :    Returns sqrt(num1*num1 + num2*num2) */ 
     590                 : PHP_FUNCTION(hypot)
     591               0 : {
     592                 :         zval **num1, **num2;
     593                 : 
     594               0 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &num1, &num2) == FAILURE) {
     595               0 :                 WRONG_PARAM_COUNT;
     596                 :         }
     597               0 :         convert_to_double_ex(num1);
     598               0 :         convert_to_double_ex(num2);
     599                 : #if HAVE_HYPOT
     600               0 :         Z_DVAL_P(return_value) = hypot(Z_DVAL_PP(num1), Z_DVAL_PP(num2));
     601                 : #elif defined(_MSC_VER)
     602                 :         Z_DVAL_P(return_value) = _hypot(Z_DVAL_PP(num1), Z_DVAL_PP(num2));
     603                 : #else
     604                 :         Z_DVAL_P(return_value) = sqrt((Z_DVAL_PP(num1) * Z_DVAL_PP(num1)) +
     605                 :                 (Z_DVAL_PP(num2) * Z_DVAL_PP(num2)));
     606                 : #endif
     607               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
     608                 : }
     609                 : /* }}} */
     610                 : 
     611                 : /* {{{ proto float deg2rad(float number)
     612                 :    Converts the number in degrees to the radian equivalent */
     613                 : PHP_FUNCTION(deg2rad)
     614               0 : {
     615                 :         zval **deg;
     616                 : 
     617               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &deg) == FAILURE) {
     618               0 :                 WRONG_PARAM_COUNT;
     619                 :         }
     620               0 :         convert_to_double_ex(deg);
     621               0 :         RETVAL_DOUBLE((Z_DVAL_PP(deg) / 180.0) * M_PI);
     622                 : }
     623                 : /* }}} */
     624                 : 
     625                 : /* {{{ proto float rad2deg(float number)
     626                 :    Converts the radian number to the equivalent number in degrees */
     627                 : PHP_FUNCTION(rad2deg)
     628               0 : {
     629                 :         zval **rad;
     630                 : 
     631               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &rad) == FAILURE) {
     632               0 :                 WRONG_PARAM_COUNT;
     633                 :         }
     634               0 :         convert_to_double_ex(rad);
     635               0 :         RETVAL_DOUBLE((Z_DVAL_PP(rad) / M_PI) * 180);
     636                 : }
     637                 : /* }}} */
     638                 : 
     639                 : /* {{{ _php_math_basetolong */
     640                 : /*
     641                 :  * Convert a string representation of a base(2-36) number to a long.
     642                 :  */
     643                 : PHPAPI long _php_math_basetolong(zval *arg, int base)
     644               0 : {
     645               0 :         long num = 0, digit, onum;
     646                 :         int i;
     647                 :         char c, *s;
     648                 : 
     649               0 :         if (Z_TYPE_P(arg) != IS_STRING || base < 2 || base > 36) {
     650               0 :                 return 0;
     651                 :         }
     652                 : 
     653               0 :         s = Z_STRVAL_P(arg);
     654                 : 
     655               0 :         for (i = Z_STRLEN_P(arg); i > 0; i--) {
     656               0 :                 c = *s++;
     657                 :                 
     658               0 :                 digit = (c >= '0' && c <= '9') ? c - '0'
     659                 :                         : (c >= 'A' && c <= 'Z') ? c - 'A' + 10
     660                 :                         : (c >= 'a' && c <= 'z') ? c - 'a' + 10
     661                 :                         : base;
     662                 :                 
     663               0 :                 if (digit >= base) {
     664               0 :                         continue;
     665                 :                 }
     666                 : 
     667               0 :                 onum = num;
     668               0 :                 num = num * base + digit;
     669               0 :                 if (num > onum)
     670               0 :                         continue;
     671                 : 
     672                 :                 {
     673                 :                         TSRMLS_FETCH();
     674                 : 
     675               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number '%s' is too big to fit in long", s);
     676               0 :                         return LONG_MAX;
     677                 :                 }
     678                 :         }
     679                 : 
     680               0 :         return num;
     681                 : }
     682                 : /* }}} */
     683                 : 
     684                 : /* {{{ _php_math_basetozval */
     685                 : /*
     686                 :  * Convert a string representation of a base(2-36) number to a zval.
     687                 :  */
     688                 : PHPAPI int _php_math_basetozval(zval *arg, int base, zval *ret)
     689               0 : {
     690               0 :         long num = 0;
     691               0 :         double fnum = 0;
     692                 :         int i;
     693               0 :         int mode = 0;
     694                 :         char c, *s;
     695                 :         long cutoff;
     696                 :         int cutlim;
     697                 : 
     698               0 :         if (Z_TYPE_P(arg) != IS_STRING || base < 2 || base > 36) {
     699               0 :                 return FAILURE;
     700                 :         }
     701                 : 
     702               0 :         s = Z_STRVAL_P(arg);
     703                 : 
     704               0 :         cutoff = LONG_MAX / base;
     705               0 :         cutlim = LONG_MAX % base;
     706                 :         
     707               0 :         for (i = Z_STRLEN_P(arg); i > 0; i--) {
     708               0 :                 c = *s++;
     709                 : 
     710                 :                 /* might not work for EBCDIC */
     711               0 :                 if (c >= '0' && c <= '9') 
     712               0 :                         c -= '0';
     713               0 :                 else if (c >= 'A' && c <= 'Z') 
     714               0 :                         c -= 'A' - 10;
     715               0 :                 else if (c >= 'a' && c <= 'z') 
     716               0 :                         c -= 'a' - 10;
     717                 :                 else
     718                 :                         continue;
     719                 : 
     720               0 :                 if (c >= base)
     721               0 :                         continue;
     722                 :                 
     723               0 :                 switch (mode) {
     724                 :                 case 0: /* Integer */
     725               0 :                         if (num < cutoff || (num == cutoff && c <= cutlim)) {
     726               0 :                                 num = num * base + c;
     727               0 :                                 break;
     728                 :                         } else {
     729               0 :                                 fnum = num;
     730               0 :                                 mode = 1;
     731                 :                         }
     732                 :                         /* fall-through */
     733                 :                 case 1: /* Float */
     734               0 :                         fnum = fnum * base + c;
     735                 :                 }       
     736                 :         }
     737                 : 
     738               0 :         if (mode == 1) {
     739               0 :                 ZVAL_DOUBLE(ret, fnum);
     740                 :         } else {
     741               0 :                 ZVAL_LONG(ret, num);
     742                 :         }
     743               0 :         return SUCCESS;
     744                 : }
     745                 : /* }}} */
     746                 : 
     747                 : /* {{{ _php_math_longtobase */
     748                 : /*
     749                 :  * Convert a long to a string containing a base(2-36) representation of
     750                 :  * the number.
     751                 :  */
     752                 : PHPAPI char * _php_math_longtobase(zval *arg, int base)
     753               0 : {
     754                 :         static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
     755                 :         char buf[(sizeof(unsigned long) << 3) + 1];
     756                 :         char *ptr, *end;
     757                 :         unsigned long value;
     758                 : 
     759               0 :         if (Z_TYPE_P(arg) != IS_LONG || base < 2 || base > 36) {
     760               0 :                 return STR_EMPTY_ALLOC();
     761                 :         }
     762                 : 
     763               0 :         value = Z_LVAL_P(arg);
     764                 : 
     765               0 :         end = ptr = buf + sizeof(buf) - 1;
     766               0 :         *ptr = '\0';
     767                 : 
     768                 :         do {
     769               0 :                 *--ptr = digits[value % base];
     770               0 :                 value /= base;
     771               0 :         } while (ptr > buf && value);
     772                 : 
     773               0 :         return estrndup(ptr, end - ptr);
     774                 : }
     775                 : /* }}} */
     776                 : 
     777                 : /* {{{ _php_math_zvaltobase */
     778                 : /*
     779                 :  * Convert a zval to a string containing a base(2-36) representation of
     780                 :  * the number.
     781                 :  */
     782                 : PHPAPI char * _php_math_zvaltobase(zval *arg, int base TSRMLS_DC)
     783               0 : {
     784                 :         static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
     785                 : 
     786               0 :         if ((Z_TYPE_P(arg) != IS_LONG && Z_TYPE_P(arg) != IS_DOUBLE) || base < 2 || base > 36) {
     787               0 :                 return STR_EMPTY_ALLOC();
     788                 :         }
     789                 : 
     790               0 :         if (Z_TYPE_P(arg) == IS_DOUBLE) {
     791               0 :                 double fvalue = floor(Z_DVAL_P(arg)); /* floor it just in case */
     792                 :                 char *ptr, *end;
     793                 :                 char buf[(sizeof(double) << 3) + 1];
     794                 : 
     795                 :                 /* Don't try to convert +/- infinity */
     796               0 :                 if (fvalue == HUGE_VAL || fvalue == -HUGE_VAL) {
     797               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number too large");
     798               0 :                         return STR_EMPTY_ALLOC();
     799                 :                 }
     800                 : 
     801               0 :                 end = ptr = buf + sizeof(buf) - 1;
     802               0 :                 *ptr = '\0';
     803                 : 
     804                 :                 do {
     805               0 :                         *--ptr = digits[(int) fmod(fvalue, base)];
     806               0 :                         fvalue /= base;
     807               0 :                 } while (ptr > buf && fabs(fvalue) >= 1);
     808                 : 
     809               0 :                 return estrndup(ptr, end - ptr);
     810                 :         }
     811                 :         
     812               0 :         return _php_math_longtobase(arg, base);
     813                 : }       
     814                 : /* }}} */
     815                 : 
     816                 : /* {{{ proto int bindec(string binary_number)
     817                 :    Returns the decimal equivalent of the binary number */
     818                 : PHP_FUNCTION(bindec)
     819               0 : {
     820                 :         zval **arg;
     821                 :         
     822               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
     823               0 :                 WRONG_PARAM_COUNT;
     824                 :         }
     825                 : 
     826               0 :         convert_to_string_ex(arg);
     827               0 :         if(_php_math_basetozval(*arg, 2, return_value) != SUCCESS) {
     828               0 :                 RETURN_FALSE;
     829                 :         }
     830                 : }
     831                 : /* }}} */
     832                 : 
     833                 : /* {{{ proto int hexdec(string hexadecimal_number)
     834                 :    Returns the decimal equivalent of the hexadecimal number */
     835                 : PHP_FUNCTION(hexdec)
     836               0 : {
     837                 :         zval **arg;
     838                 :         
     839               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
     840               0 :                 WRONG_PARAM_COUNT;
     841                 :         }
     842                 : 
     843               0 :         convert_to_string_ex(arg);
     844                 : 
     845               0 :         if(_php_math_basetozval(*arg, 16, return_value) != SUCCESS) {
     846               0 :                 RETURN_FALSE;
     847                 :         }
     848                 : }
     849                 : /* }}} */
     850                 : 
     851                 : /* {{{ proto int octdec(string octal_number)
     852                 :    Returns the decimal equivalent of an octal string */
     853                 : PHP_FUNCTION(octdec)
     854               0 : {
     855                 :         zval **arg;
     856                 :         
     857               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
     858               0 :                 WRONG_PARAM_COUNT;
     859                 :         }
     860                 : 
     861               0 :         convert_to_string_ex(arg);
     862                 : 
     863               0 :         if(_php_math_basetozval(*arg, 8, return_value) != SUCCESS) {
     864               0 :                 RETURN_FALSE;
     865                 :         }
     866                 : }
     867                 : /* }}} */
     868                 : 
     869                 : /* {{{ proto string decbin(int decimal_number)
     870                 :    Returns a string containing a binary representation of the number */
     871                 : PHP_FUNCTION(decbin)
     872               0 : {
     873                 :         zval **arg;
     874                 :         char *result;
     875                 : 
     876               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
     877               0 :                 WRONG_PARAM_COUNT;
     878                 :         }
     879                 : 
     880               0 :         convert_to_long_ex(arg);
     881                 : 
     882               0 :         result = _php_math_longtobase(*arg, 2);
     883               0 :         Z_TYPE_P(return_value) = IS_STRING;
     884               0 :         Z_STRLEN_P(return_value) = strlen(result);
     885               0 :         Z_STRVAL_P(return_value) = result;
     886                 : }
     887                 : /* }}} */
     888                 : 
     889                 : /* {{{ proto string decoct(int decimal_number)
     890                 :    Returns a string containing an octal representation of the given number */
     891                 : PHP_FUNCTION(decoct)
     892               0 : {
     893                 :         zval **arg;
     894                 :         char *result;
     895                 : 
     896               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
     897               0 :                 WRONG_PARAM_COUNT;
     898                 :         }
     899                 : 
     900               0 :         convert_to_long_ex(arg);
     901                 : 
     902               0 :         result = _php_math_longtobase(*arg, 8);
     903               0 :         Z_TYPE_P(return_value) = IS_STRING;
     904               0 :         Z_STRLEN_P(return_value) = strlen(result);
     905               0 :         Z_STRVAL_P(return_value) = result;
     906                 : }
     907                 : /* }}} */
     908                 : 
     909                 : /* {{{ proto string dechex(int decimal_number)
     910                 :    Returns a string containing a hexadecimal representation of the given number */
     911                 : PHP_FUNCTION(dechex)
     912               0 : {
     913                 :         zval **arg;
     914                 :         char *result;
     915                 : 
     916               0 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
     917               0 :                 WRONG_PARAM_COUNT;
     918                 :         }
     919                 : 
     920               0 :         convert_to_long_ex(arg);
     921                 : 
     922               0 :         result = _php_math_longtobase(*arg, 16);
     923               0 :         Z_TYPE_P(return_value) = IS_STRING;
     924               0 :         Z_STRLEN_P(return_value) = strlen(result);
     925               0 :         Z_STRVAL_P(return_value) = result;
     926                 : }
     927                 : /* }}} */
     928                 : 
     929                 : /* {{{ proto string base_convert(string number, int frombase, int tobase)
     930                 :    Converts a number in a string from any base <= 36 to any base <= 36 */
     931                 : PHP_FUNCTION(base_convert)
     932               0 : {
     933                 :         zval **number, **frombase, **tobase, temp;
     934                 :         char *result;
     935                 : 
     936               0 :         if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &number, &frombase, &tobase) == FAILURE) {
     937               0 :                 WRONG_PARAM_COUNT;
     938                 :         }
     939               0 :         convert_to_string_ex(number);
     940               0 :         convert_to_long_ex(frombase);
     941               0 :         convert_to_long_ex(tobase);
     942               0 :         if (Z_LVAL_PP(frombase) < 2 || Z_LVAL_PP(frombase) > 36) {
     943               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid `from base' (%ld)", Z_LVAL_PP(frombase));
     944               0 :                 RETURN_FALSE;
     945                 :         }
     946               0 :         if (Z_LVAL_PP(tobase) < 2 || Z_LVAL_PP(tobase) > 36) {
     947               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid `to base' (%ld)", Z_LVAL_PP(tobase));
     948               0 :                 RETURN_FALSE;
     949                 :         }
     950                 : 
     951               0 :         if(_php_math_basetozval(*number, Z_LVAL_PP(frombase), &temp) != SUCCESS) {
     952               0 :                 RETURN_FALSE;
     953                 :         }
     954               0 :         result = _php_math_zvaltobase(&temp, Z_LVAL_PP(tobase) TSRMLS_CC);
     955               0 :         RETVAL_STRING(result, 0);
     956                 : } 
     957                 : /* }}} */
     958                 : 
     959                 : /* {{{ _php_math_number_format 
     960                 : */
     961                 : PHPAPI char *_php_math_number_format(double d, int dec, char dec_point, char thousand_sep)
     962               0 : {
     963               0 :         char *tmpbuf = NULL, *resbuf;
     964                 :         char *s, *t;  /* source, target */
     965                 :         char *dp;
     966                 :         int integral;
     967               0 :         int tmplen, reslen=0;
     968               0 :         int count=0;
     969               0 :         int is_negative=0;
     970                 : 
     971               0 :         if (d < 0) {
     972               0 :                 is_negative = 1;
     973               0 :                 d = -d;
     974                 :         }
     975                 : 
     976               0 :         dec = MAX(0, dec);
     977               0 :         PHP_ROUND_WITH_FUZZ(d, dec);
     978                 : 
     979               0 :         tmplen = spprintf(&tmpbuf, 0, "%.*F", dec, d);
     980                 : 
     981               0 :         if (tmpbuf == NULL || !isdigit((int)tmpbuf[0])) {
     982               0 :                 return tmpbuf;
     983                 :         }
     984                 : 
     985                 :         /* find decimal point, if expected */
     986               0 :         if (dec) {
     987               0 :                 dp = strpbrk(tmpbuf, ".,");
     988                 :         } else {
     989               0 :                 dp = NULL;
     990                 :         }
     991                 : 
     992                 :         /* calculate the length of the return buffer */
     993               0 :         if (dp) {
     994               0 :                 integral = dp - tmpbuf;
     995                 :         } else {
     996                 :                 /* no decimal point was found */
     997               0 :                 integral = tmplen;
     998                 :         }
     999                 : 
    1000                 :         /* allow for thousand separators */
    1001               0 :         if (thousand_sep) {
    1002               0 :                 integral += (integral-1) / 3;
    1003                 :         }
    1004                 :         
    1005               0 :         reslen = integral;
    1006                 :         
    1007               0 :         if (dec) {
    1008               0 :                 reslen += dec;
    1009                 : 
    1010               0 :                 if (dec_point) {
    1011               0 :                         reslen++;
    1012                 :                 }
    1013                 :         }
    1014                 : 
    1015                 :         /* add a byte for minus sign */
    1016               0 :         if (is_negative) {
    1017               0 :                 reslen++;
    1018                 :         }
    1019               0 :         resbuf = (char *) emalloc(reslen+1); /* +1 for NUL terminator */
    1020                 : 
    1021               0 :         s = tmpbuf+tmplen-1;
    1022               0 :         t = resbuf+reslen;
    1023               0 :         *t-- = '\0';
    1024                 : 
    1025                 :         /* copy the decimal places.
    1026                 :          * Take care, as the sprintf implementation may return less places than
    1027                 :          * we requested due to internal buffer limitations */
    1028               0 :         if (dec) {
    1029               0 :                 int declen = dp ? s - dp : 0;
    1030               0 :                 int topad = dec > declen ? dec - declen : 0;
    1031                 : 
    1032                 :                 /* pad with '0's */
    1033               0 :                 while (topad--) {
    1034               0 :                         *t-- = '0';
    1035                 :                 }
    1036                 :                 
    1037               0 :                 if (dp) {
    1038               0 :                         s -= declen + 1; /* +1 to skip the point */
    1039               0 :                         t -= declen;
    1040                 : 
    1041                 :                         /* now copy the chars after the point */
    1042               0 :                         memcpy(t + 1, dp + 1, declen);
    1043                 :                 }
    1044                 : 
    1045                 :                 /* add decimal point */
    1046               0 :                 if (dec_point) {
    1047               0 :                         *t-- = dec_point;
    1048                 :                 }
    1049                 :         }
    1050                 : 
    1051                 :         /* copy the numbers before the decimal point, adding thousand
    1052                 :          * separator every three digits */
    1053               0 :         while(s >= tmpbuf) {
    1054               0 :                 *t-- = *s--;
    1055               0 :                 if (thousand_sep && (++count%3)==0 && s>=tmpbuf) {
    1056               0 :                         *t-- = thousand_sep;
    1057                 :                 }
    1058                 :         }
    1059                 : 
    1060                 :         /* and a minus sign, if needed */
    1061               0 :         if (is_negative) {
    1062               0 :                 *t-- = '-';
    1063                 :         }
    1064                 : 
    1065               0 :         efree(tmpbuf);
    1066                 :         
    1067               0 :         return resbuf;
    1068                 : }
    1069                 : /* }}} */
    1070                 : 
    1071                 : /* {{{ proto string number_format(float number [, int num_decimal_places [, string dec_seperator, string thousands_seperator]])
    1072                 :    Formats a number with grouped thousands */
    1073                 : PHP_FUNCTION(number_format)
    1074               0 : {
    1075                 :         zval **num, **dec, **t_s, **d_p;
    1076               0 :         char thousand_sep=',', dec_point='.';
    1077                 :         
    1078               0 :         switch(ZEND_NUM_ARGS()) {
    1079                 :         case 1:
    1080               0 :                 if (zend_get_parameters_ex(1, &num)==FAILURE) {
    1081               0 :                         RETURN_FALSE;
    1082                 :                 }
    1083               0 :                 convert_to_double_ex(num);
    1084               0 :                 RETURN_STRING(_php_math_number_format(Z_DVAL_PP(num), 0, dec_point, thousand_sep), 0);
    1085                 :                 break;
    1086                 :         case 2:
    1087               0 :                 if (zend_get_parameters_ex(2, &num, &dec)==FAILURE) {
    1088               0 :                         RETURN_FALSE;
    1089                 :                 }
    1090               0 :                 convert_to_double_ex(num);
    1091               0 :                 convert_to_long_ex(dec);
    1092               0 :                 RETURN_STRING(_php_math_number_format(Z_DVAL_PP(num), Z_LVAL_PP(dec), dec_point, thousand_sep), 0);
    1093                 :                 break;
    1094                 :         case 4:
    1095               0 :                 if (zend_get_parameters_ex(4, &num, &dec, &d_p, &t_s)==FAILURE) {
    1096               0 :                         RETURN_FALSE;
    1097                 :                 }
    1098               0 :                 convert_to_double_ex(num);
    1099               0 :                 convert_to_long_ex(dec);
    1100                 : 
    1101               0 :                 if (Z_TYPE_PP(d_p) != IS_NULL) { 
    1102               0 :                         convert_to_string_ex(d_p);
    1103               0 :                         if (Z_STRLEN_PP(d_p)>=1) {
    1104               0 :                                 dec_point=Z_STRVAL_PP(d_p)[0];
    1105               0 :                         } else if (Z_STRLEN_PP(d_p)==0) {
    1106               0 :                                 dec_point=0;
    1107                 :                         }
    1108                 :                 }
    1109               0 :                 if (Z_TYPE_PP(t_s) != IS_NULL) {
    1110               0 :                         convert_to_string_ex(t_s);
    1111               0 :                         if (Z_STRLEN_PP(t_s)>=1) {
    1112               0 :                                 thousand_sep=Z_STRVAL_PP(t_s)[0];
    1113               0 :                         } else if(Z_STRLEN_PP(t_s)==0) {
    1114               0 :                                 thousand_sep=0; 
    1115                 :                         }
    1116                 :                 }
    1117               0 :                 RETURN_STRING(_php_math_number_format(Z_DVAL_PP(num), Z_LVAL_PP(dec), dec_point, thousand_sep), 0);
    1118                 :                 break;
    1119                 :         default:
    1120               0 :                 WRONG_PARAM_COUNT;
    1121                 :                 break;
    1122                 :         }
    1123                 : }
    1124                 : /* }}} */
    1125                 : 
    1126                 : /* {{{ proto float fmod(float x, float y)
    1127                 :    Returns the remainder of dividing x by y as a float */
    1128                 : PHP_FUNCTION(fmod)
    1129               0 : {
    1130                 :         double num1, num2;
    1131                 : 
    1132               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd",  &num1, &num2) == FAILURE) {
    1133               0 :                 return;
    1134                 :         }
    1135                 :         
    1136               0 :         Z_DVAL_P(return_value) = fmod(num1, num2);
    1137               0 :         Z_TYPE_P(return_value) = IS_DOUBLE;
    1138                 : }
    1139                 : /* }}} */
    1140                 : 
    1141                 : 
    1142                 : 
    1143                 : /*
    1144                 :  * Local variables:
    1145                 :  * tab-width: 4
    1146                 :  * c-basic-offset: 4
    1147                 :  * End:
    1148                 :  * vim600: fdm=marker
    1149                 :  * vim: noet sw=4 ts=4
    1150                 :  */

Generated by: LTP GCOV extension version 1.5