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