diff options
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/bento.info | 2 | ||||
-rw-r--r-- | numpy/core/setup.py | 34 | ||||
-rw-r--r-- | numpy/core/src/multiarray/common.h | 24 | ||||
-rw-r--r-- | numpy/core/src/multiarray/ctors.c | 1 | ||||
-rw-r--r-- | numpy/core/src/multiarray/multiarraymodule.c | 1 | ||||
-rw-r--r-- | numpy/core/src/private/npy_partition.h | 558 | ||||
-rw-r--r-- | numpy/core/src/private/scalarmathmodule.h.src | 42 | ||||
-rw-r--r-- | numpy/core/src/scalarmathmodule.c.src | 128 |
8 files changed, 70 insertions, 720 deletions
diff --git a/numpy/core/bento.info b/numpy/core/bento.info index cad7ffe8c..ffddc00fa 100644 --- a/numpy/core/bento.info +++ b/numpy/core/bento.info @@ -10,6 +10,7 @@ Library: src/npymath/halffloat.c CompiledLibrary: npysort Sources: + src/private/npy_partition.h.src src/npysort/quicksort.c.src, src/npysort/mergesort.c.src, src/npysort/heapsort.c.src, @@ -28,6 +29,7 @@ Library: src/umath/umath_tests.c.src Extension: scalarmath Sources: + src/private/scalarmathmodule.h.src src/scalarmathmodule.c.src Extension: _dotblas Sources: diff --git a/numpy/core/setup.py b/numpy/core/setup.py index 8c6c287a1..75c129a5d 100644 --- a/numpy/core/setup.py +++ b/numpy/core/setup.py @@ -529,6 +529,10 @@ def configuration(parent_package='',top_path=None): def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" + # put private include directory in build_dir on search path + # allows using code generation in headers headers + config.add_include_dirs(join(build_dir, "src", "private")) + target = join(build_dir, header_dir, '_numpyconfig.h') d = os.path.dirname(target) if not os.path.exists(d): @@ -679,12 +683,12 @@ def configuration(parent_package='',top_path=None): subst_dict["posix_mathlib"] = posix_mlib subst_dict["msvc_mathlib"] = msvc_mlib + npymath_sources = [join('src', 'npymath', 'npy_math.c.src'), + join('src', 'npymath', 'ieee754.c.src'), + join('src', 'npymath', 'npy_math_complex.c.src'), + join('src', 'npymath', 'halffloat.c')] config.add_installed_library('npymath', - sources=[join('src', 'npymath', 'npy_math.c.src'), - join('src', 'npymath', 'ieee754.c.src'), - join('src', 'npymath', 'npy_math_complex.c.src'), - join('src', 'npymath', 'halffloat.c'), - get_mathlib_info], + sources=npymath_sources + [get_mathlib_info], install_dir='lib') config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config", subst_dict) @@ -696,11 +700,14 @@ def configuration(parent_package='',top_path=None): ####################################################################### # This library is created for the build but it is not installed + npysort_sources=[join('src', 'npysort', 'quicksort.c.src'), + join('src', 'npysort', 'mergesort.c.src'), + join('src', 'npysort', 'heapsort.c.src'), + join('src','private', 'npy_partition.h.src'), + join('src', 'npysort', 'selection.c.src')] config.add_library('npysort', - sources = [join('src', 'npysort', 'quicksort.c.src'), - join('src', 'npysort', 'mergesort.c.src'), - join('src', 'npysort', 'heapsort.c.src'), - join('src', 'npysort', 'selection.c.src')]) + sources=npysort_sources, + include_dirs=[]) ####################################################################### @@ -774,7 +781,9 @@ def configuration(parent_package='',top_path=None): join('include', 'numpy', 'ndarraytypes.h'), join('include', 'numpy', 'npy_1_7_deprecated_api.h'), join('include', 'numpy', '_numpyconfig.h.in'), - ] + # add library sources as distuils does not consider libraries + # dependencies + ] + npysort_sources + npymath_sources multiarray_src = [ join('src', 'multiarray', 'arrayobject.c'), @@ -887,7 +896,7 @@ def configuration(parent_package='',top_path=None): generate_umath_py, join('src', 'umath', 'simd.inc.src'), join(codegen_dir, 'generate_ufunc_api.py'), - join('src', 'private', 'ufunc_override.h')] + join('src', 'private', 'ufunc_override.h')] + npymath_sources if not ENABLE_SEPARATE_COMPILATION: umath_deps.extend(umath_src) @@ -912,11 +921,12 @@ def configuration(parent_package='',top_path=None): config.add_extension('scalarmath', sources = [join('src', 'scalarmathmodule.c.src'), + join('src', 'private', 'scalarmathmodule.h.src'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, generate_ufunc_api], - depends = deps, + depends = deps + npymath_sources, libraries = ['npymath'], ) diff --git a/numpy/core/src/multiarray/common.h b/numpy/core/src/multiarray/common.h index ffb571b2e..f05698b9e 100644 --- a/numpy/core/src/multiarray/common.h +++ b/numpy/core/src/multiarray/common.h @@ -84,30 +84,6 @@ npy_is_aligned(const void * p, const npy_uintp alignment) } } -/* - * writes result of a * b into r - * returns 1 if a * b overflowed else returns 0 - */ -static NPY_INLINE int -npy_mul_with_overflow_intp(npy_intp * r, npy_intp a, npy_intp b) -{ - const npy_intp half_sz = (((npy_intp)1 << (sizeof(a) * 8 / 2)) - 1); - - *r = a * b; - - /* - * avoid expensive division on common no overflow case - * could be improved via compiler intrinsics e.g. via clang - * __builtin_mul_with_overflow, gcc __int128 or cpu overflow flags - */ - if (NPY_UNLIKELY((a | b) >= half_sz) && - a != 0 && b > NPY_MAX_INTP / a) { - return 1; - } - - return 0; -} - #include "ucsnarrow.h" #endif diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index bef3feec1..1b7e1c428 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -25,6 +25,7 @@ #include "datetime_strings.h" #include "array_assign.h" #include "mapping.h" /* for array_item_asarray */ +#include "scalarmathmodule.h" /* for npy_mul_with_overflow_intp */ /* * Reading from a file or a string. diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c index f0ada8618..ea879c226 100644 --- a/numpy/core/src/multiarray/multiarraymodule.c +++ b/numpy/core/src/multiarray/multiarraymodule.c @@ -54,6 +54,7 @@ NPY_NO_EXPORT int NPY_NUMUSERTYPES = 0; #include "array_assign.h" #include "common.h" #include "ufunc_override.h" +#include "scalarmathmodule.h" /* for npy_mul_with_overflow_intp */ /* Only here for API compatibility */ NPY_NO_EXPORT PyTypeObject PyBigArray_Type; diff --git a/numpy/core/src/private/npy_partition.h b/numpy/core/src/private/npy_partition.h deleted file mode 100644 index f2b684d3a..000000000 --- a/numpy/core/src/private/npy_partition.h +++ /dev/null @@ -1,558 +0,0 @@ - -/* - ***************************************************************************** - ** This file was autogenerated from a template DO NOT EDIT!!!! ** - ** Changes should be made to the original source (.src) file ** - ***************************************************************************** - */ - -#line 1 -/* - ***************************************************************************** - ** IMPORTANT NOTE for npy_partition.h.src -> npy_partition.h ** - ***************************************************************************** - * The template file loops.h.src is not automatically converted into - * loops.h by the build system. If you edit this file, you must manually - * do the conversion using numpy/distutils/conv_template.py from the - * command line as follows: - * - * $ cd <NumPy source root directory> - * $ python numpy/distutils/conv_template.py numpy/core/src/private/npy_partition.h.src - * $ - */ - - -#ifndef __NPY_PARTITION_H__ -#define __NPY_PARTITION_H__ - - -#include "npy_sort.h" - -/* Python include is for future object sorts */ -#include <Python.h> -#include <numpy/npy_common.h> -#include <numpy/ndarraytypes.h> - -#define NPY_MAX_PIVOT_STACK 50 - - -#line 43 - -int introselect_bool(npy_bool *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_bool(npy_bool *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_byte(npy_byte *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_byte(npy_byte *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_ubyte(npy_ubyte *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_ubyte(npy_ubyte *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_short(npy_short *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_short(npy_short *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_ushort(npy_ushort *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_ushort(npy_ushort *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_int(npy_int *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_int(npy_int *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_uint(npy_uint *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_uint(npy_uint *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_long(npy_long *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_long(npy_long *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_ulong(npy_ulong *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_ulong(npy_ulong *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_longlong(npy_longlong *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_longlong(npy_longlong *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_ulonglong(npy_ulonglong *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_ulonglong(npy_ulonglong *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_half(npy_ushort *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_half(npy_ushort *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_float(npy_float *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_float(npy_float *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_double(npy_double *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_double(npy_double *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_longdouble(npy_longdouble *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_longdouble(npy_longdouble *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_cfloat(npy_cfloat *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_cfloat(npy_cfloat *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_cdouble(npy_cdouble *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_cdouble(npy_cdouble *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - -#line 43 - -int introselect_clongdouble(npy_clongdouble *v, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); -int aintroselect_clongdouble(npy_clongdouble *v, npy_intp* tosort, npy_intp num, - npy_intp kth, - npy_intp * pivots, - npy_intp * npiv, - void *NOT_USED); - - - - -int introselect_string(npy_char *vec, npy_intp cnt, npy_intp kth, PyArrayObject *arr); -int aintroselect_string(npy_char *vec, npy_intp *ind, npy_intp cnt, npy_intp kth, void *null); - - -int introselect_unicode(npy_ucs4 *vec, npy_intp cnt, npy_intp kth, PyArrayObject *arr); -int aintroselect_unicode(npy_ucs4 *vec, npy_intp *ind, npy_intp cnt, npy_intp kth, void *null); - -int npy_introselect(void *base, size_t num, size_t size, size_t kth, npy_comparator cmp); - -typedef struct { - enum NPY_TYPES typenum; - PyArray_PartitionFunc * part[NPY_NSELECTS]; - PyArray_ArgPartitionFunc * argpart[NPY_NSELECTS]; -} part_map; - -static part_map _part_map[] = { -#line 87 - { - NPY_BOOL, - { - (PyArray_PartitionFunc *)&introselect_bool, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_bool, - } - }, - -#line 87 - { - NPY_BYTE, - { - (PyArray_PartitionFunc *)&introselect_byte, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_byte, - } - }, - -#line 87 - { - NPY_UBYTE, - { - (PyArray_PartitionFunc *)&introselect_ubyte, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_ubyte, - } - }, - -#line 87 - { - NPY_SHORT, - { - (PyArray_PartitionFunc *)&introselect_short, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_short, - } - }, - -#line 87 - { - NPY_USHORT, - { - (PyArray_PartitionFunc *)&introselect_ushort, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_ushort, - } - }, - -#line 87 - { - NPY_INT, - { - (PyArray_PartitionFunc *)&introselect_int, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_int, - } - }, - -#line 87 - { - NPY_UINT, - { - (PyArray_PartitionFunc *)&introselect_uint, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_uint, - } - }, - -#line 87 - { - NPY_LONG, - { - (PyArray_PartitionFunc *)&introselect_long, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_long, - } - }, - -#line 87 - { - NPY_ULONG, - { - (PyArray_PartitionFunc *)&introselect_ulong, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_ulong, - } - }, - -#line 87 - { - NPY_LONGLONG, - { - (PyArray_PartitionFunc *)&introselect_longlong, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_longlong, - } - }, - -#line 87 - { - NPY_ULONGLONG, - { - (PyArray_PartitionFunc *)&introselect_ulonglong, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_ulonglong, - } - }, - -#line 87 - { - NPY_HALF, - { - (PyArray_PartitionFunc *)&introselect_half, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_half, - } - }, - -#line 87 - { - NPY_FLOAT, - { - (PyArray_PartitionFunc *)&introselect_float, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_float, - } - }, - -#line 87 - { - NPY_DOUBLE, - { - (PyArray_PartitionFunc *)&introselect_double, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_double, - } - }, - -#line 87 - { - NPY_LONGDOUBLE, - { - (PyArray_PartitionFunc *)&introselect_longdouble, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_longdouble, - } - }, - -#line 87 - { - NPY_CFLOAT, - { - (PyArray_PartitionFunc *)&introselect_cfloat, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_cfloat, - } - }, - -#line 87 - { - NPY_CDOUBLE, - { - (PyArray_PartitionFunc *)&introselect_cdouble, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_cdouble, - } - }, - -#line 87 - { - NPY_CLONGDOUBLE, - { - (PyArray_PartitionFunc *)&introselect_clongdouble, - }, - { - (PyArray_ArgPartitionFunc *)&aintroselect_clongdouble, - } - }, - -}; - - -static NPY_INLINE PyArray_PartitionFunc * -get_partition_func(int type, NPY_SELECTKIND which) -{ - npy_intp i; - if (which >= NPY_NSELECTS) { - return NULL; - } - for (i = 0; i < sizeof(_part_map)/sizeof(_part_map[0]); i++) { - if (type == _part_map[i].typenum) { - return _part_map[i].part[which]; - } - } - return NULL; -} - - -static NPY_INLINE PyArray_ArgPartitionFunc * -get_argpartition_func(int type, NPY_SELECTKIND which) -{ - npy_intp i; - if (which >= NPY_NSELECTS) { - return NULL; - } - for (i = 0; i < sizeof(_part_map)/sizeof(_part_map[0]); i++) { - if (type == _part_map[i].typenum) { - return _part_map[i].argpart[which]; - } - } - return NULL; -} - -#endif diff --git a/numpy/core/src/private/scalarmathmodule.h.src b/numpy/core/src/private/scalarmathmodule.h.src new file mode 100644 index 000000000..48507a54b --- /dev/null +++ b/numpy/core/src/private/scalarmathmodule.h.src @@ -0,0 +1,42 @@ +/* + * some overflow checking integer arithmetic + */ +#include <numpy/npy_common.h> + +#ifndef __NPY_SCALARMATHMODULE_H__ +#define __NPY_SCALARMATHMODULE_H__ + +/**begin repeat + * #name = int, uint, long, ulong, + * longlong, ulonglong, intp# + * #type = npy_int, npy_uint, npy_long, npy_ulong, + * npy_longlong, npy_ulonglong, npy_intp# + * #MAX = NPY_MAX_INT, NPY_MAX_UINT, NPY_MAX_LONG, NPY_MAX_ULONG, + * NPY_MAX_LONGLONG, NPY_MAX_ULONGLONG, NPY_MAX_INTP# + */ + +/* + * writes result of a * b into r + * returns 1 if a * b overflowed else returns 0 + */ +static NPY_INLINE int +npy_mul_with_overflow_@name@(@type@ * r, @type@ a, @type@ b) +{ + const @type@ half_sz = (((@type@)1 << (sizeof(a) * 8 / 2)) - 1); + + *r = a * b; + /* + * avoid expensive division on common no overflow case + * could be improved via compiler intrinsics e.g. via clang + * __builtin_mul_with_overflow, gcc __int128 or cpu overflow flags + */ + if (NPY_UNLIKELY((a | b) >= half_sz) && + a != 0 && b > @MAX@ / a) { + return 1; + } + + return 0; +} +/**end repeat**/ + +#endif diff --git a/numpy/core/src/scalarmathmodule.c.src b/numpy/core/src/scalarmathmodule.c.src index d789a3dd4..fac8aa399 100644 --- a/numpy/core/src/scalarmathmodule.c.src +++ b/numpy/core/src/scalarmathmodule.c.src @@ -16,129 +16,7 @@ #include "npy_pycompat.h" #include "numpy/halffloat.h" - -/** numarray adapted routines.... **/ - -/* - * Note that the C standard requires signed/unsigned integral - * types of the same rank to have the same width. - */ - -#if NPY_SIZEOF_LONGLONG == 64 - -static int -ulonglong_overflow(npy_ulonglong a, npy_ulonglong b) -{ - npy_ulonglong ah, al, bh, bl, w, x, y, z; - unsigned long long mask = 0xFFFFFFFFL; - - ah = (a >> 32); - al = (a & mask); - bh = (b >> 32); - bl = (b & mask); - - /* 128-bit product: z*2**64 + (x+y)*2**32 + w */ - w = al*bl; - x = bh*al; - y = ah*bl; - z = ah*bh; - - /* *c = ((x + y)<<32) + w; */ - return z || (x >> 32) || (y >> 32) || - (((x & mask) + (y & mask) + (w >> 32)) >> 32); -} - -static int -slonglong_overflow(npy_longlong a0, npy_longlong b0) -{ - npy_ulonglong a, b; - npy_ulonglong ah, al, bh, bl, w, x, y, z; - long long mask = 0xFFFFFFFFL; - - a = (a0 < 0) ? -a0 : a0; - b = (b0 < 0) ? -b0 : b0; - - ah = (a >> 32); - al = (a & mask); - bh = (b >> 32); - bl = (b & mask); - - w = al*bl; - x = bh*al; - y = ah*bl; - z = ah*bh; - - return z || (x >> 31) || (y >> 31) || - (((x & mask) + (y & mask) + (w >> 32)) >> 31); -} - -#elif NPY_SIZEOF_LONGLONG == 128 - -static int -ulonglong_overflow(npy_ulonglong a, npy_ulonglong b) -{ - npy_ulonglong ah, al, bh, bl, w, x, y, z; - unsigned long long mask = 0xFFFFFFFFFFFFFFFFL; - - ah = (a >> 64); - al = (a & mask); - bh = (b >> 64); - bl = (b & mask); - - /* 128-bit product: z*2**64 + (x+y)*2**32 + w */ - w = al*bl; - x = bh*al; - y = ah*bl; - z = ah*bh; - - /* *c = ((x + y)<<32) + w; */ - return z || (x >> 64) || (y >> 64) || - (((x & mask) + (y & mask) + (w >> 64)) >> 64); -} - -static int -slonglong_overflow(npy_longlong a0, npy_longlong b0) -{ - npy_ulonglong a, b; - npy_ulonglong ah, al, bh, bl, w, x, y, z; - long long mask = 0xFFFFFFFFFFFFFFFFL; - - a = (a0 < 0) ? -a0 : a0; - b = (b0 < 0) ? -b0 : b0; - - ah = (a >> 64); - al = (a & mask); - bh = (b >> 64); - bl = (b & mask); - - w = al*bl; - x = bh*al; - y = ah*bl; - z = ah*bh; - - return z || (x >> 63) || (y >> 63) || - (((x & mask) + (y & mask) + (w >> 64)) >> 63); -} - -#else - -static int -ulonglong_overflow(npy_ulonglong NPY_UNUSED(a), npy_ulonglong NPY_UNUSED(b)) -{ - return 0; -} - -static int -slonglong_overflow(npy_longlong NPY_UNUSED(a0), npy_longlong NPY_UNUSED(b0)) -{ - return 0; -} - -#endif - - -/** end direct numarray code **/ - +#include "scalarmathmodule.h" /* Basic operations: * @@ -245,13 +123,11 @@ static void * #type = npy_int, npy_uint, npy_long, npy_ulong, * npy_longlong, npy_ulonglong# * #SIZE = INT*2, LONG*2, LONGLONG*2# - * #char = (s, u)*3# */ #if NPY_SIZEOF_LONGLONG == NPY_SIZEOF_@SIZE@ static void @name@_ctype_multiply(@type@ a, @type@ b, @type@ *out) { - *out = a * b; - if (@char@longlong_overflow(a, b)) { + if (npy_mul_with_overflow_@name@(out, a, b)) { npy_set_floatstatus_overflow(); } return; |