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 assert (sum <= 0x7FFFFFFE);
73 assert (a <= 0x7FFFFFFE);
74 assert (b <= 0x7FFFFFFE);
75 assert (c <= 0x7FFFFFFE);
76 assert (d <= 0x7FFFFFFE);
77 assert (e <= 0x7FFFFFFE);
78 assert (f <= 0x7FFFFFFE);
79 return mod_mac2(mod_mac(sum, a, b), c, d, e, f);
80}
81
83 assert (sum <= 0x7FFFFFFE);
84 assert (a <= 0x7FFFFFFE);
85 assert (b <= 0x7FFFFFFE);
86 assert (c <= 0x7FFFFFFE);
87 assert (d <= 0x7FFFFFFE);
88 assert (e <= 0x7FFFFFFE);
89 assert (f <= 0x7FFFFFFE);
90 assert (g <= 0x7FFFFFFE);
91 assert (h <= 0x7FFFFFFE);
92 return mod_mac2(mod_mac2(sum, a, b, c, d), e, f, g, h);
93}
94
95/* The two constants x and y are special cases because they are easier to
96 * multiply by on 32-bit systems. They are used as multipliers in the random
97 * number generator. The techniques for fast multiplication by these
98 * particular values are from:
99 *
100 * Pierre L'Ecuyer, Francois Blouin, and Raymond Couture. 1993. A search
101 * for good multiple recursive random number generators. ACM Trans. Model.
102 * Comput. Simul. 3, 2 (April 1993), 87-98. DOI=10.1145/169702.169698
103 * http://doi.acm.org/10.1145/169702.169698
104 *
105 * Pierre L'Ecuyer. 1990. Random numbers for simulation. Commun. ACM 33, 10
106 * (October 1990), 85-97. DOI=10.1145/84537.84555
107 * http://doi.acm.org/10.1145/84537.84555
108 */
109
111 static const int32_t q = 20 /* UINT32_C(0x7FFFFFFF) / 107374182 */;
112 static const int32_t r = 7 /* UINT32_C(0x7FFFFFFF) % 107374182 */;
113 int_fast32_t result = (int_fast32_t)(a) / q;
114 result = 107374182 * ((int_fast32_t)(a) - result * q) - result * r;
115 result += (result < 0 ? 0x7FFFFFFF : 0);
116 assert ((uint_fast32_t)(result) == mod_mul(a, 107374182));
117 return (uint_fast32_t)result;
118}
119
121 static const int32_t q = 20554 /* UINT32_C(0x7FFFFFFF) / 104480 */;
122 static const int32_t r = 1727 /* UINT32_C(0x7FFFFFFF) % 104480 */;
123 int_fast32_t result = (int_fast32_t)(a) / q;
124 result = 104480 * ((int_fast32_t)(a) - result * q) - result * r;
125 result += (result < 0 ? 0x7FFFFFFF : 0);
126 assert ((uint_fast32_t)(result) == mod_mul(a, 104480));
127 return (uint_fast32_t)result;
128}
129
131 uint_fast32_t result = mod_add(sum, mod_mul_y(a));
132 assert (result == mod_mac(sum, a, 104480));
133 return result;
134}
135
136#endif /* MOD_ARITH_32BIT_H */
uint_fast32_t mod_mul_x(uint_fast32_t a)
uint_fast32_t mod_mac_y(uint_fast32_t sum, uint_fast32_t a)
uint_fast32_t mod_mul_y(uint_fast32_t a)
Mac OS X ATTR com apple quarantine q
Definition ._remapper.cpp:1
uint64_t uint_fast64_t
Definition stdint.h:111
uint32_t uint_fast32_t
Definition stdint.h:110
int32_t int_fast32_t
Definition stdint.h:106
signed int int32_t
Definition stdint.h:77