Back to index

php5  5.3.10
zend_multiply.h
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | Zend Engine                                                          |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 2.00 of the Zend license,     |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.zend.com/license/2_00.txt.                                |
00011    | If you did not receive a copy of the Zend license and are unable to  |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@zend.com so we can mail you a copy immediately.              |
00014    +----------------------------------------------------------------------+
00015    | Authors: Sascha Schumann <sascha@schumann.cx>                        |
00016    |          Ard Biesheuvel <ard@ard.nu>                                 |
00017    +----------------------------------------------------------------------+
00018 */
00019 
00020 /* $Id: zend_multiply.h 321634 2012-01-01 13:15:04Z felipe $ */
00021 
00022 #if defined(__i386__) && defined(__GNUC__)
00023 
00024 #define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do {     \
00025        long __tmpvar;                                                                                           \
00026        __asm__ ("imul %3,%0\n"                                                                           \
00027               "adc $0,%1"                                                                                \
00028                      : "=r"(__tmpvar),"=r"(usedval)                                               \
00029                      : "0"(a), "r"(b), "1"(0));                                                   \
00030        if (usedval) (dval) = (double) (a) * (double) (b);                           \
00031        else (lval) = __tmpvar;                                                                           \
00032 } while (0)
00033 
00034 #elif SIZEOF_LONG == 4 && defined(HAVE_ZEND_LONG64)
00035 
00036 #define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do {     \
00037        zend_long64 __result = (zend_long64) (a) * (zend_long64) (b);  \
00038        if (__result > LONG_MAX || __result < LONG_MIN) {                            \
00039               (dval) = (double) __result;                                                         \
00040               (usedval) = 1;                                                                                    \
00041        } else {                                                                                                 \
00042               (lval) = (long) __result;                                                           \
00043               (usedval) = 0;                                                                                    \
00044        }                                                                                                               \
00045 } while (0)
00046 
00047 #else
00048 
00049 #define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do {            \
00050        long   __lres  = (a) * (b);                                                                       \
00051        long double __dres  = (long double)(a) * (long double)(b);                                               \
00052        long double __delta = (long double) __lres - __dres;                                              \
00053        if ( ((usedval) = (( __dres + __delta ) != __dres))) {                       \
00054               (dval) = __dres;                                                                                  \
00055        } else {                                                                                                        \
00056               (lval) = __lres;                                                                                  \
00057        }                                                                                                                      \
00058 } while (0)
00059 
00060 #endif