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

LTP GCOV extension - code coverage report
Current view: directory - standard - math.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 451
Code covered: 91.4 % Executed lines: 412
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:23 +0000 (5 days ago)

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