cvs: php4 /ext/standard math.c
| From: | Sascha Schumann | Date: | Wed, 19 Sep 2001 10:57:50 +0000 |
| Subject: | cvs: php4 /ext/standard math.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-7466@lists.php.net to get a copy of this message | ||
sas Wed Sep 19 06:57:50 2001 EDT
Modified files:
/php4/ext/standard math.c
Log:
Rewrite _php_match_basetozval to need only one multiplication
per iteration and avoid the U?LONG_MAX hassle.
Index: php4/ext/standard/math.c
diff -u php4/ext/standard/math.c:1.59 php4/ext/standard/math.c:1.60
--- php4/ext/standard/math.c:1.59 Tue Sep 18 16:05:05 2001
+++ php4/ext/standard/math.c Wed Sep 19 06:57:50 2001
@@ -19,7 +19,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: math.c,v 1.59 2001/09/18 20:05:05 sterling Exp $ */
+/* $Id: math.c,v 1.60 2001/09/19 10:57:50 sas Exp $ */
#include "php.h"
#include "php_math.h"
@@ -706,10 +706,10 @@
*/
PHPAPI int
_php_math_basetozval(zval *arg, int base, zval *ret) {
- long mult = 1, num = 0, digit;
- double fmult, fnum;
+ long num = 0, digit, onum;
+ double fnum;
int i;
- int f_mode = 0;
+ int mode = 0;
char c, *s;
if (Z_TYPE_P(arg) != IS_STRING || base < 2 || base > 36) {
@@ -718,38 +718,34 @@
s = Z_STRVAL_P(arg);
- for (i = Z_STRLEN_P(arg) - 1; i >= 0; i--) {
- c = toupper(s[i]);
- if (c >= '0' && c <= '9') {
- digit = (c - '0');
- } else if (c >= 'A' && c <= 'Z') {
- digit = (c - 'A' + 10);
- } else {
- continue;
- }
- if (digit >= base) {
+ for (i = Z_STRLEN_P(arg); i >= 0; i--) {
+ c = *s++;
+
+ digit = (c >= '0' && c <= '9') ? c - '0'
+ : (c >= 'A' && c <= 'Z') ? c - 'A' + 10
+ : (c >= 'a' && c <= 'z') ? c - 'a' + 10
+ : base;
+
+ if (digit >= base)
continue;
- }
- if(!f_mode && (!mult || digit > LONG_MAX/mult || num > LONG_MAX-mult*digit)) {
- f_mode = 1;
- if(!mult) {
- fmult = (ulong) ULONG_MAX + 1;
- } else {
- fmult = (ulong) mult;
- }
- fnum = (ulong) num;
- }
- if(f_mode) {
- fnum += fmult * digit;
- fmult *= base;
- } else {
- num += mult * digit;
- mult *= base;
- }
+ switch (mode) {
+ case 0: /* Integer */
+ onum = num;
+ num = num * base + digit;
+
+ if (num > onum)
+ break; /* No overflow, continue */
+
+ fnum = onum;
+ mode = 1;
+ /* fall-through */
+ case 1: /* Float */
+ fnum = fnum * base + digit;
+ }
}
- if(f_mode) {
+ if (mode == 1) {
ZVAL_DOUBLE(ret, fnum);
} else {
ZVAL_LONG(ret, num);