[PHP-DEV] CVS update: php3 From: zeev (php-dev <email protected>)
Date: 05/23/98

Date: Saturday May 23, 1998 @ 11:38
Author: zeev

Update of /repository/php3
In directory asf:/tmp/cvs-serv22559

Modified Files:
        operators.c php.h
Log Message:
Use BC if numbers may lose accuracy, instead of dealing with them as strings.

Index: php3/operators.c
diff -c php3/operators.c:1.85 php3/operators.c:1.86
*** php3/operators.c:1.85 Sat May 16 16:54:40 1998
--- php3/operators.c Sat May 23 11:38:50 1998
***************
*** 29,40 ****
   */
  
  
! /* $Id: operators.c,v 1.85 1998/05/16 20:54:40 rasmus Exp $ */
  
  #ifdef THREAD_SAFE
  #include "tls.h"
  #endif
  #include "php.h"
  #include <stdio.h>
  #if HAVE_STRING_H
  #include <string.h>
--- 29,41 ----
   */
  
  
! /* $Id: operators.c,v 1.86 1998/05/23 15:38:50 zeev Exp $ */
  
  #ifdef THREAD_SAFE
  #include "tls.h"
  #endif
  #include "php.h"
+ #include "functions/number.h"
  #include <stdio.h>
  #if HAVE_STRING_H
  #include <string.h>
***************
*** 65,70 ****
--- 66,74 ----
                          case IS_DOUBLE:
                          case IS_LONG:
                                  break;
+ case IS_BC:
+ op->type = IS_DOUBLE; /* may have lost significant digits */
+ break;
                          default:
                                  op->value.lval = strtol(op->value.str.val, NULL, 10);
                                  op->type = IS_LONG;
***************
*** 1061,1067 ****
          
          if ((ret1=is_numeric_string(s1->value.str.val, s1->value.str.len, &lval1, &dval1)) &&
                  (ret2=is_numeric_string(s2->value.str.val, s2->value.str.len, &lval2, &dval2))) {
! if ((ret1==IS_DOUBLE) || (ret2==IS_DOUBLE)) {
                          result->value.dval = dval1 - dval2;
                          result->type = IS_DOUBLE;
                  } else {
--- 1065,1083 ----
          
          if ((ret1=is_numeric_string(s1->value.str.val, s1->value.str.len, &lval1, &dval1)) &&
                  (ret2=is_numeric_string(s2->value.str.val, s2->value.str.len, &lval2, &dval2))) {
! if ((ret1==IS_BC) || (ret2==IS_BC)) {
! bc_num first, second;
!
! /* use the BC math library to compare the numbers */
! init_num(&first);
! init_num(&second);
! str2num(&first,s1->value.str.val,100); /* this scale should do */
! str2num(&second,s2->value.str.val,100); /* ditto */
! result->value.lval = bc_compare(first,second);
! result->type = IS_LONG;
! free_num(&first);
! free_num(&second);
! } else if ((ret1==IS_DOUBLE) || (ret2==IS_DOUBLE)) {
                          result->value.dval = dval1 - dval2;
                          result->type = IS_DOUBLE;
                  } else {
***************
*** 1081,1086 ****
--- 1097,1103 ----
  /* returns 0 for non-numeric string
   * returns IS_DOUBLE for floating point string, and assigns the value to *dval (if it's not NULL)
   * returns IS_LONG for integer strings, and assigns the value to *lval (if it's not NULL)
+ * returns IS_BC if the number might lose accuracy when converted to a double
   */
   
  #if 1
***************
*** 1090,1101 ****
          double local_dval;
          char *end_ptr;
  
! /*
! strtod() will lose significant digits on integers with more than 16 digits.
! So, use this rather crude fix for now until we figure out a better way to handle
! this limitation.
! */
! if (!length || length > 16) {
                  return 0;
          }
          
--- 1107,1113 ----
          double local_dval;
          char *end_ptr;
  
! if (!length) {
                  return 0;
          }
          
***************
*** 1114,1120 ****
                  if (dval) {
                          *dval = local_dval;
                  }
! return IS_DOUBLE;
          }
          
          return 0;
--- 1126,1149 ----
                  if (dval) {
                          *dval = local_dval;
                  }
! if (length>16) {
! register char *ptr=str, *end=str+length;
!
! while(ptr<end) {
! switch(*ptr++) {
! case 'e':
! case 'E':
! /* scientific notation, not handled by the BC library */
! return IS_DOUBLE;
! break;
! default:
! break;
! }
! }
! return IS_BC;
! } else {
! return IS_DOUBLE;
! }
          }
          
          return 0;
Index: php3/php.h
diff -c php3/php.h:1.13 php3/php.h:1.14
*** php3/php.h:1.13 Fri May 22 15:18:21 1998
--- php3/php.h Sat May 23 11:38:51 1998
***************
*** 28,34 ****
     +----------------------------------------------------------------------+
   */
  
! /* $Id: php.h,v 1.13 1998/05/22 19:18:21 shane Exp $ */
  
  #ifndef _PHP_H
  #define _PHP_H
--- 28,34 ----
     +----------------------------------------------------------------------+
   */
  
! /* $Id: php.h,v 1.14 1998/05/23 15:38:51 zeev Exp $ */
  
  #ifndef _PHP_H
  #define _PHP_H
***************
*** 321,326 ****
--- 321,327 ----
  #define IS_CLASS 0x80
  #define IS_OBJECT 0x100
  #define IS_NULL 0x200
+ #define IS_BC 0x400
  
  #define VALID_FUNCTION (IS_USER_FUNCTION|IS_INTERNAL_FUNCTION)
  #define IS_HASH (IS_ARRAY | IS_OBJECT)