File: GB_int64_mult.h

package info (click to toggle)
suitesparse 1%3A7.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 254,920 kB
  • sloc: ansic: 1,134,743; cpp: 46,133; makefile: 4,875; fortran: 2,087; java: 1,826; sh: 996; ruby: 725; python: 495; asm: 371; sed: 166; awk: 44
file content (52 lines) | stat: -rw-r--r-- 2,720 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//------------------------------------------------------------------------------
// GB_int64_mult: multiplying two integer values safely; result z is int64_t
//------------------------------------------------------------------------------

// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2025, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

//------------------------------------------------------------------------------

// This macro computes the same thing as GB_uint64_multiply, except that it
// does not return a boolean ok flag to indicate whether or not integer
// overflow is detected.  Instead, it just computes c as INT64_MAX if overflow
// occurs.  Both inputs x and y must be >= 0.

#ifndef GB_INT64_MULT
#define GB_INT64_MULT(z,x,y)                            \
{                                                       \
    uint64_t a = (uint64_t) (x) ;                       \
    uint64_t b = (uint64_t) (y) ;                       \
    if (a == 0 || b == 0)                               \
    {                                                   \
        (z) = 0 ;                                       \
    }                                                   \
    else                                                \
    {                                                   \
        uint64_t a1 = a >> 30 ;                         \
        uint64_t b1 = b >> 30 ;                         \
        if (a1 > 0 && b1 > 0)                           \
        {                                               \
            (z) = INT64_MAX ;                           \
        }                                               \
        else                                            \
        {                                               \
            uint64_t a0 = a & 0x3FFFFFFFL ;             \
            uint64_t b0 = b & 0x3FFFFFFFL ;             \
            uint64_t t0 = a1*b0 ;                       \
            uint64_t t1 = a0*b1 ;                       \
            if (t0 >= 0x40000000L || t1 >= 0x40000000L) \
            {                                           \
                (z) = INT64_MAX ;                       \
            }                                           \
            else                                        \
            {                                           \
                uint64_t t2 = t0 + t1 ;                 \
                uint64_t c = (t2 << 30) + a0*b0 ;       \
                (z) = (int64_t) c ;                     \
            }                                           \
        }                                               \
    }                                                   \
}
#endif