COMBINATORIAL_BLAS 1.6
 
Loading...
Searching...
No Matches
mod_arith_32bit.h
Go to the documentation of this file.
1/* Copyright (C) 2010 The Trustees of Indiana University. */
2/* */
3/* Use, modification and distribution is subject to the Boost Software */
4/* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at */
5/* http://www.boost.org/LICENSE_1_0.txt) */
6/* */
7/* Authors: Jeremiah Willcock */
8/* Andrew Lumsdaine */
9
10#ifndef MOD_ARITH_32BIT_H
11#define MOD_ARITH_32BIT_H
12
13#include <stdint.h>
14#include <assert.h>
15
16/* Various modular arithmetic operations for modulus 2^31-1 (0x7FFFFFFF).
17 * These may need to be tweaked to get acceptable performance on some platforms
18 * (especially ones without conditional moves). */
19
20static inline uint_fast32_t mod_add(uint_fast32_t a, uint_fast32_t b) {
22 assert (a <= 0x7FFFFFFE);
23 assert (b <= 0x7FFFFFFE);
24#if 0
25 return (a + b) % 0x7FFFFFFF;
26#else
27 x = a + b; /* x <= 0xFFFFFFFC */
28 x = (x >= 0x7FFFFFFF) ? (x - 0x7FFFFFFF) : x;
29 return x;
30#endif
31}
32
33static inline uint_fast32_t mod_mul(uint_fast32_t a, uint_fast32_t b) {
34 uint_fast64_t temp;
35 uint_fast32_t temp2;
36 assert (a <= 0x7FFFFFFE);
37 assert (b <= 0x7FFFFFFE);
38#if 0
39 return (uint_fast32_t)((uint_fast64_t)a * b % 0x7FFFFFFF);
40#else
41 temp = (uint_fast64_t)a * b; /* temp <= 0x3FFFFFFE00000004 */
42 temp2 = (uint_fast32_t)(temp & 0x7FFFFFFF) + (uint_fast32_t)(temp >> 31); /* temp2 <= 0xFFFFFFFB */
43 return (temp2 >= 0x7FFFFFFF) ? (temp2 - 0x7FFFFFFF) : temp2;
44#endif
45}
46
47static inline uint_fast32_t mod_mac(uint_fast32_t sum, uint_fast32_t a, uint_fast32_t b) {
48 uint_fast64_t temp;
49 uint_fast32_t temp2;
50 assert (sum <= 0x7FFFFFFE);
51 assert (a <= 0x7FFFFFFE);
52 assert (b <= 0x7FFFFFFE);
53#if 0
54 return (uint_fast32_t)(((uint_fast64_t)a * b + sum) % 0x7FFFFFFF);
55#else
56 temp = (uint_fast64_t)a * b + sum; /* temp <= 0x3FFFFFFE80000002 */
57 temp2 = (uint_fast32_t)(temp & 0x7FFFFFFF) + (uint_fast32_t)(temp >> 31); /* temp2 <= 0xFFFFFFFC */
58 return (temp2 >= 0x7FFFFFFF) ? (temp2 - 0x7FFFFFFF) : temp2;
59#endif
60}
61
63 assert (sum <= 0x7FFFFFFE);
64 assert (a <= 0x7FFFFFFE);
65 assert (b <= 0x7FFFFFFE);
66 assert (c <= 0x7FFFFFFE);
67 assert (d <= 0x7FFFFFFE);
68 return mod_mac(mod_mac(sum, a, b), c, d);
69}
70
72 uint_fast64_t temp;
73 assert (sum <= 0x7FFFFFFE);
74 assert (a <= 0x7FFFFFFE);
75 assert (b <= 0x7FFFFFFE);
76 assert (c <= 0x7FFFFFFE);
77 assert (d <= 0x7FFFFFFE);
78 assert (e <= 0x7FFFFFFE);
79 assert (f <= 0x7FFFFFFE);
80 return mod_mac2(mod_mac(sum, a, b), c, d, e, f);
81}
82
84 uint_fast64_t temp;
85 assert (sum <= 0x7FFFFFFE);
86 assert (a <= 0x7FFFFFFE);
87 assert (b <= 0x7FFFFFFE);
88 assert (c <= 0x7FFFFFFE);
89 assert (d <= 0x7FFFFFFE);
90 assert (e <= 0x7FFFFFFE);
91 assert (f <= 0x7FFFFFFE);
92 assert (g <= 0x7FFFFFFE);
93 assert (h <= 0x7FFFFFFE);
94 return mod_mac2(mod_mac2(sum, a, b, c, d), e, f, g, h);
95}
96
97/* The two constants x and y are special cases because they are easier to
98 * multiply by on 32-bit systems. They are used as multipliers in the random
99 * number generator. The techniques for fast multiplication by these
100 * particular values are in L'Ecuyer's papers; we don't use them yet. */
101
102static inline uint_fast32_t mod_mul_x(uint_fast32_t a) {
103 return mod_mul(a, 107374182);
104}
105
106static inline uint_fast32_t mod_mul_y(uint_fast32_t a) {
107 return mod_mul(a, 104480);
108}
109
110static inline uint_fast32_t mod_mac_y(uint_fast32_t sum, uint_fast32_t a) {
111 return mod_mac(sum, a, 104480);
112}
113
114#endif /* MOD_ARITH_32BIT_H */
uint64_t uint_fast64_t
Definition stdint.h:111
uint32_t uint_fast32_t
Definition stdint.h:110