1/*
2 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @library /lib/testlibrary/
27 * @build jdk.testlibrary.*
28 * @run main BitTwiddle
29 * @bug     4495754 8078672
30 * @summary Basic test for int bit twiddling (use -Dseed=X to set PRNG seed)
31 * @author  Josh Bloch
32 * @key randomness
33 */
34
35import java.util.Random;
36import jdk.testlibrary.RandomFactory;
37import static java.lang.Integer.*;
38
39public class BitTwiddle {
40    private static final int N = 1000; // # of repetitions per test
41
42    public static void main(String args[]) {
43        Random rnd = RandomFactory.getRandom();
44
45        if (highestOneBit(0) != 0)
46            throw new RuntimeException("a");
47        if (highestOneBit(-1) != MIN_VALUE)
48            throw new RuntimeException("b");
49        if (highestOneBit(1) != 1)
50            throw new RuntimeException("c");
51
52        if (lowestOneBit(0) != 0)
53            throw new RuntimeException("d");
54        if (lowestOneBit(-1) != 1)
55            throw new RuntimeException("e");
56        if (lowestOneBit(MIN_VALUE) != MIN_VALUE)
57            throw new RuntimeException("f");
58
59        for (int i = 0; i < N; i++) {
60            int x = rnd.nextInt();
61
62            String expected = new StringBuilder()
63                .append(leftpad(toBinaryString(x), 32))
64                .reverse().toString();
65
66            String actual = leftpad(toBinaryString(reverse(x)), 32);
67
68            if (!expected.equals(actual)) {
69                throw new RuntimeException("reverse: \n" +
70                        expected + " \n" + actual);
71            }
72        }
73
74        for (int i = 0; i < N; i++) {
75            int x = rnd.nextInt();
76            if (highestOneBit(x) != reverse(lowestOneBit(reverse(x))))
77                throw new RuntimeException("g: " + toHexString(x));
78        }
79
80        if (numberOfLeadingZeros(0) != SIZE)
81            throw new RuntimeException("h");
82        if (numberOfLeadingZeros(-1) != 0)
83            throw new RuntimeException("i");
84        if (numberOfLeadingZeros(1) != (SIZE - 1))
85            throw new RuntimeException("j");
86
87        if (numberOfTrailingZeros(0) != SIZE)
88            throw new RuntimeException("k");
89        if (numberOfTrailingZeros(1) != 0)
90            throw new RuntimeException("l");
91        if (numberOfTrailingZeros(MIN_VALUE) != (SIZE - 1))
92            throw new RuntimeException("m");
93
94        for (int i = 0; i < N; i++) {
95            int x = rnd.nextInt();
96            if (numberOfLeadingZeros(x) != numberOfTrailingZeros(reverse(x)))
97                throw new RuntimeException("n: " + toHexString(x));
98        }
99
100        if (bitCount(0) != 0)
101                throw new RuntimeException("o");
102
103        for (int i = 0; i < SIZE; i++) {
104            int pow2 = 1 << i;
105            if (bitCount(pow2) != 1)
106                throw new RuntimeException("p: " + i);
107            if (bitCount(pow2 -1) != i)
108                throw new RuntimeException("q: " + i);
109        }
110
111        for (int i = 0; i < N; i++) {
112            int x = rnd.nextInt();
113            if (bitCount(x) != bitCount(reverse(x)))
114                throw new RuntimeException("r: " + toHexString(x));
115        }
116
117        for (int i = 0; i < N; i++) {
118            int x = rnd.nextInt();
119            int dist = rnd.nextInt();
120            if (bitCount(x) != bitCount(rotateRight(x, dist)))
121                throw new RuntimeException("s: " + toHexString(x) +
122                                           toHexString(dist));
123            if (bitCount(x) != bitCount(rotateLeft(x, dist)))
124                throw new RuntimeException("t: " + toHexString(x) +
125                                           toHexString(dist));
126            if (rotateRight(x, dist) != rotateLeft(x, -dist))
127                throw new RuntimeException("u: " + toHexString(x) +
128                                           toHexString(dist));
129            if (rotateRight(x, -dist) != rotateLeft(x, dist))
130                throw new RuntimeException("v: " + toHexString(x) +
131                                           toHexString(dist));
132        }
133
134        if (signum(0) != 0 || signum(1) != 1 || signum(-1) != -1
135            || signum(MIN_VALUE) != -1 || signum(MAX_VALUE) != 1)
136            throw new RuntimeException("w");
137
138        for (int i = 0; i < N; i++) {
139            int x = rnd.nextInt();
140            int sign = (x < 0 ? -1 : (x == 0 ? 0 : 1));
141            if (signum(x) != sign)
142                throw new RuntimeException("x: " + toHexString(x));
143        }
144
145        if(reverseBytes(0xaabbccdd) != 0xddccbbaa)
146            throw new RuntimeException("y");
147
148        for (int i = 0; i < N; i++) {
149            int x = rnd.nextInt();
150            if (bitCount(x) != bitCount(reverseBytes(x)))
151                throw new RuntimeException("z: " + toHexString(x));
152        }
153    }
154
155    private static String leftpad(String s, int width) {
156        String r = s;
157        for (int c = 0; c < width - s.length(); c++) {
158            r = "0" + r;
159        }
160        return r;
161    }
162}
163