1 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
3 #ident "$Id$"
4 /*======
5 This file is part of TokuDB
6
7
8 Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
9
10 TokuDBis is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License, version 2,
12 as published by the Free Software Foundation.
13
14 TokuDB is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with TokuDB. If not, see <http://www.gnu.org/licenses/>.
21
22 ======= */
23
24 #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
25
26 #include <stdio.h>
27 #include <stdint.h>
28 #include <stdlib.h>
29 #include <assert.h>
30 #include <sys/types.h>
31 #include <tokudb_math.h>
32 using namespace tokudb;
33
sign_extend(uint length_bits,int64_t n)34 static int64_t sign_extend(uint length_bits, int64_t n) {
35 return n | ~((1ULL<<(length_bits-1))-1);
36 }
37
test_int_range(uint length_bits)38 static void test_int_range(uint length_bits) {
39 assert(int_high_endpoint(length_bits) == (int64_t)((1ULL<<(length_bits-1))-1));
40 assert(int_low_endpoint(length_bits) == sign_extend(length_bits, 1ULL<<(length_bits-1)));
41 }
42
test_int8()43 static void test_int8() {
44 printf("%s\n", __FUNCTION__);
45 test_int_range(8);
46 int64_t max = (1LL << 7);
47 for (int64_t x = -max; x <= max-1; x++) {
48 for (int64_t y = -max; y <= max-1; y++) {
49 bool over;
50 int64_t n, m;
51 n = int_add(x, y, 8, &over);
52 m = x + y;
53 if (m > max-1)
54 assert(over);
55 else if (m < -max)
56 assert(over);
57 else {
58 assert(!over);
59 assert(n == m);
60 }
61 n = int_sub(x, y, 8, &over);
62 m = x - y;
63 if (m > max-1)
64 assert(over);
65 else if (m < -max)
66 assert(over);
67 else {
68 assert(!over);
69 asset(n == m);
70 }
71 }
72 }
73 }
74
test_int16()75 static void test_int16() {
76 printf("%s\n", __FUNCTION__);
77 test_int_range(16);
78 int64_t max = (1LL << 15);
79 for (int64_t x = -max; x <= max-1; x++) {
80 for (int64_t y = -max; y <= max-1; y++) {
81 bool over;
82 int64_t n, m;
83 n = int_add(x, y, 16, &over);
84 m = x + y;
85 if (m > max-1)
86 assert(over);
87 else if (m < -max)
88 assert(over);
89 else {
90 assert(!over);
91 assert(n == m);
92 }
93 n = int_sub(x, y, 16, &over);
94 m = x - y;
95 if (m > max-1)
96 assert(over);
97 else if (m < -max)
98 assert(over);
99 else {
100 assert(!over);
101 assert(n == m);
102 }
103 }
104 }
105 }
106
test_int24()107 static void test_int24() {
108 printf("%s\n", __FUNCTION__);
109 test_int_range(24);
110 int64_t s;
111 bool over;
112
113 s = int_add(1, (1ULL<<23)-1, 24, &over); assert(over);
114 s = int_add((1ULL<<23)-1, 1, 24, &over); assert(over);
115 s = int_sub(-1, (1ULL<<23), 24, &over);
116 assert(!over);
117 assert(s == (1ULL<<23)-1);
118 s = int_sub((1ULL<<23), 1, 24, &over); assert(over);
119
120 s = int_add(0, 0, 24, &over);
121 assert(!over);
122 assert(s == 0);
123 s = int_sub(0, 0, 24, &over);
124 assert(!over);
125 assert(s == 0);
126 s = int_add(0, -1, 24, &over);
127 assert(!over);
128 assert(s == -1);
129 s = int_sub(0, 1, 24, &over);
130 assert(!over);
131 assert(s == -1);
132 s = int_add(0, (1ULL<<23), 24, &over);
133 assert(!over);
134 assert((s & ((1ULL<<24)-1)) == (1ULL<<23));
135 s = int_sub(0, (1ULL<<23)-1, 24, &over);
136 assert(!over);
137 assert((s & ((1ULL<<24)-1)) == (1ULL<<23)+1);
138
139 s = int_add(-1, 0, 24, &over);
140 assert(!over);
141 assert(s == -1);
142 s = int_add(-1, 1, 24, &over);
143 assert(!over);
144 assert(s == 0);
145 s = int_sub(-1, -1, 24, &over);
146 assert(!over);
147 assert(s == 0);
148 s = int_sub(-1, (1ULL<<23)-1, 24, &over);
149 assert(!over);
150 assert((s & ((1ULL<<24)-1)) == (1ULL<<23));
151 }
152
test_int32()153 static void test_int32() {
154 printf("%s\n", __FUNCTION__);
155 test_int_range(32);
156 int64_t s;
157 bool over;
158
159 s = int_add(1, (1ULL<<31)-1, 32, &over); assert(over);
160 s = int_add((1ULL<<31)-1, 1, 32, &over); assert(over);
161 s = int_sub(-1, (1ULL<<31), 32, &over);
162 assert(s == (1ULL<<31)-1);
163 assert(!over);
164 s = int_sub((1ULL<<31), 1, 32, &over); assert(over);
165
166 s = int_add(0, 0, 32, &over);
167 assert(s == 0);
168 assert(!over);
169 s = int_sub(0, 0, 32, &over);
170 assert(s == 0);
171 assert(!over);
172 s = int_add(0, -1, 32, &over);
173 assert(s == -1);
174 assert(!over);
175 s = int_sub(0, 1, 32, &over);
176 assert(s == -1);
177 assert(!over);
178 s = int_add(0, (1ULL<<31), 32, &over);
179 assert((s & ((1ULL<<32)-1)) == (1ULL<<31));
180 assert(!over);
181 s = int_sub(0, (1ULL<<31)-1, 32, &over);
182 assert((s & ((1ULL<<32)-1)) == (1ULL<<31)+1);
183 assert(!over);
184
185 s = int_add(-1, 0, 32, &over);
186 assert(s == -1);
187 assert(!over);
188 s = int_add(-1, 1, 32, &over);
189 assert(s == 0);
190 assert(!over);
191 s = int_sub(-1, -1, 32, &over);
192 assert(s == 0);
193 assert(!over);
194 s = int_sub(-1, (1ULL<<31)-1, 32, &over);
195 assert((s & ((1ULL<<32)-1)) == (1ULL<<31));
196 assert(!over);
197 }
198
test_int64()199 static void test_int64() {
200 printf("%s\n", __FUNCTION__);
201 test_int_range(64);
202 int64_t s;
203 bool over;
204
205 s = int_add(1, (1ULL<<63)-1, 64, &over); assert(over);
206 s = int_add((1ULL<<63)-1, 1, 64, &over); assert(over);
207 s = int_sub(-1, (1ULL<<63), 64, &over);
208 assert(s == (1ULL<<63)-1);
209 assert(!over);
210 s = int_sub((1ULL<<63), 1, 64, &over); assert(over);
211
212 s = int_add(0, 0, 64, &over);
213 assert(s == 0);
214 assert(!over);
215 s = int_sub(0, 0, 64, &over);
216 assert(s == 0);
217 assert(!over);
218 s = int_add(0, -1, 64, &over);
219 assert(s == -1);
220 assert(!over);
221 s = int_sub(0, 1, 64, &over);
222 assert(s == -1);
223 assert(!over);
224 s = int_add(0, (1ULL<<63), 64, &over);
225 assert(s == (int64_t)(1ULL<<63));
226 assert(!over);
227 s = int_sub(0, (1ULL<<63)-1, 64, &over);
228 assert(s == (int64_t)((1ULL<<63)+1));
229 assert(!over);
230
231 s = int_add(-1, 0, 64, &over);
232 assert(s == -1);
233 assert(!over);
234 s = int_add(-1, 1, 64, &over);
235 assert(s == 0);
236 assert(!over);
237 s = int_sub(-1, -1, 64, &over);
238 assert(s == 0);
239 assert(!over);
240 s = int_sub(-1, (1ULL<<63)-1, 64, &over);
241 assert(s == (int64_t)(1ULL<<63));
242 assert(!over);
243 }
244
test_int_sign(uint length_bits)245 static void test_int_sign(uint length_bits) {
246 printf("%s %u\n", __FUNCTION__, length_bits);
247 int64_t n;
248
249 n = int_high_endpoint(length_bits);
250 assert(int_sign_extend(n, length_bits) == n);
251 n = (1ULL<<(length_bits-1));
252 assert(int_sign_extend(n, length_bits) == -n);
253 }
254
test_int_sign()255 static void test_int_sign() {
256 test_int_sign(8);
257 test_int_sign(16);
258 test_int_sign(24);
259 test_int_sign(32);
260 test_int_sign(64);
261 }
262
main()263 int main() {
264 test_int_sign();
265 test_int8();
266 test_int16();
267 test_int24();
268 test_int32();
269 test_int64();
270 return 0;
271 }
272
273