This code fails on 64-bit archs because it relies on the accuracy of a double to be sufficient to represent LONG_MAX. The patch adresses it by checking for overflow by reversing the calculation instead of casting to a double and back to long.


#include "build/php5-cvs/Zend/zend_multiply.h"


#define LONG_MIN (1L << (8*sizeof(long)-1))
#define LONG_MAX ~LONG_MIN

int main()
{
  long res = 0;
  double d = 0;
  int overflow;

  /* obviously (LONG_MAX-1) * 1 can be represented by a long */
  ZEND_SIGNED_MULTIPLY_LONG(LONG_MAX-1,1,res,d,overflow);

  printf("res: %ld/%.4f, %soverflow\n", result, d, overflow?"":"no ");
  return 0;
}



--
Ard
--- Zend/zend_multiply.h        Sun Mar  7 13:59:35 2004
+++ Zend/zend_multiply.h.new    Wed Mar  3 09:14:04 2004
@@ -33,13 +33,13 @@
 #else
 
 #define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do {      \
-       double __tmpvar = (double) (a) * (double) (b);                                 
 \
+       long __tmpvar = (a) * (b);                                                     
                         \
                                                                                       
                                                 \
-       if (__tmpvar >= LONG_MAX || __tmpvar <= LONG_MIN) {                            
 \
-               (dval) = __tmpvar;                                                     
                                 \
+       if ((a) != 0 && __tmpvar / (a) != (b)) {                                       
         \
+               (dval) = (double)(a) * (double)(b);                                    
                 \
                (usedval) = 1;                                                         
                                 \
        } else {                                                                       
                                         \
-               (lval) = (a) * (b);                                                    
                                 \
+               (lval) = __tmpvar;                                                     
                                 \
                (usedval) = 0;                                                         
                                 \
        }                                                                              
                                                 \
 } while (0)

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to