1+ package com .thealgorithms .bitmanipulation ;
2+
3+ import static org .junit .jupiter .api .Assertions .*;
4+ import org .junit .jupiter .api .Test ;
5+
6+ /**
7+ * Unit tests for BitRotate class covering typical, boundary, and edge cases.
8+ * Tests verify correct behavior for 32-bit circular bit rotations.
9+ */
10+ public class BitRotateTest {
11+
12+ // ===== rotateLeft Tests =====
13+
14+ @ Test
15+ void testRotateLeftBasic () {
16+ // Basic left rotation
17+ assertEquals (0b00000000_00000000_00000000_00000010, BitRotate .rotateLeft (1 , 1 ));
18+ assertEquals (0b00000000_00000000_00000000_00000100, BitRotate .rotateLeft (1 , 2 ));
19+ assertEquals (0b00000000_00000000_00000000_00001000, BitRotate .rotateLeft (1 , 3 ));
20+ }
21+
22+ @ Test
23+ void testRotateLeftWithCarry () {
24+ // Test bits carrying from left to right
25+ // Binary: 10000000_00000000_00000000_00000001
26+ int value = 0x80000001 ;
27+ // After left rotate by 1: 00000000_00000000_00000000_00000011
28+ assertEquals (3 , BitRotate .rotateLeft (value , 1 ));
29+
30+ // Binary: 11000000_00000000_00000000_00000000
31+ value = 0xC0000000 ;
32+ // After left rotate by 1: 10000000_00000000_00000000_00000001
33+ assertEquals (0x80000001 , BitRotate .rotateLeft (value , 1 ));
34+ }
35+
36+ @ Test
37+ void testRotateLeftShift32 () {
38+ // Shift of 32 should be same as shift of 0 (modulo behavior)
39+ int value = 0x12345678 ;
40+ assertEquals (value , BitRotate .rotateLeft (value , 32 ));
41+ assertEquals (value , BitRotate .rotateLeft (value , 64 ));
42+ assertEquals (value , BitRotate .rotateLeft (value , 96 ));
43+ }
44+
45+ @ Test
46+ void testRotateLeftShiftNormalization () {
47+ // Test that shifts > 32 are properly normalized
48+ int value = 1 ;
49+ assertEquals (BitRotate .rotateLeft (value , 1 ), BitRotate .rotateLeft (value , 33 ));
50+ assertEquals (BitRotate .rotateLeft (value , 5 ), BitRotate .rotateLeft (value , 37 ));
51+ }
52+
53+ @ Test
54+ void testRotateLeftZeroShift () {
55+ // Zero shift should return original value
56+ int value = 0xABCD1234 ;
57+ assertEquals (value , BitRotate .rotateLeft (value , 0 ));
58+ }
59+
60+ // ===== rotateRight Tests =====
61+
62+ @ Test
63+ void testRotateRightBasic () {
64+ // Basic right rotation
65+ assertEquals (0b10000000_00000000_00000000_00000000, BitRotate .rotateRight (1 , 1 ));
66+ assertEquals (0b01000000_00000000_00000000_00000000, BitRotate .rotateRight (1 , 2 ));
67+ assertEquals (0b00100000_00000000_00000000_00000000, BitRotate .rotateRight (1 , 3 ));
68+ }
69+
70+ @ Test
71+ void testRotateRightWithCarry () {
72+ // Test bits carrying from right to left
73+ // Binary: 00000000_00000000_00000000_00000011
74+ int value = 3 ;
75+ // After right rotate by 1: 10000000_00000000_00000000_00000001
76+ assertEquals (0x80000001 , BitRotate .rotateRight (value , 1 ));
77+
78+ // Binary: 00000000_00000000_00000000_00000001
79+ value = 1 ;
80+ // After right rotate by 1: 10000000_00000000_00000000_00000000
81+ assertEquals (0x80000000 , BitRotate .rotateRight (value , 1 ));
82+ }
83+
84+ @ Test
85+ void testRotateRightShift32 () {
86+ // Shift of 32 should be same as shift of 0 (modulo behavior)
87+ int value = 0x9ABCDEF0 ;
88+ assertEquals (value , BitRotate .rotateRight (value , 32 ));
89+ assertEquals (value , BitRotate .rotateRight (value , 64 ));
90+ assertEquals (value , BitRotate .rotateRight (value , 96 ));
91+ }
92+
93+ @ Test
94+ void testRotateRightShiftNormalization () {
95+ // Test that shifts > 32 are properly normalized
96+ int value = 1 ;
97+ assertEquals (BitRotate .rotateRight (value , 1 ), BitRotate .rotateRight (value , 33 ));
98+ assertEquals (BitRotate .rotateRight (value , 7 ), BitRotate .rotateRight (value , 39 ));
99+ }
100+
101+ @ Test
102+ void testRotateRightZeroShift () {
103+ // Zero shift should return original value
104+ int value = 0xDEADBEEF ;
105+ assertEquals (value , BitRotate .rotateRight (value , 0 ));
106+ }
107+
108+ // ===== Edge Case Tests =====
109+
110+ @ Test
111+ void testRotateLeftMaxValue () {
112+ // Test with maximum integer value
113+ int value = Integer .MAX_VALUE ; // 0x7FFFFFFF
114+ int rotated = BitRotate .rotateLeft (value , 1 );
115+ // MAX_VALUE << 1 should become 0xFFFFFFFE, but with rotation it becomes different
116+ assertEquals (0xFFFFFFFE , rotated );
117+ }
118+
119+ @ Test
120+ void testRotateRightMinValue () {
121+ // Test with minimum integer value (treated as unsigned)
122+ int value = Integer .MIN_VALUE ; // 0x80000000
123+ int rotated = BitRotate .rotateRight (value , 1 );
124+ // MIN_VALUE >>> 1 should become 0x40000000, but with rotation from left
125+ assertEquals (0x40000000 , rotated );
126+ }
127+
128+ @ Test
129+ void testRotateAllOnes () {
130+ // Test with all bits set
131+ int value = 0xFFFFFFFF ; // All ones
132+ assertEquals (value , BitRotate .rotateLeft (value , 13 ));
133+ assertEquals (value , BitRotate .rotateRight (value , 27 ));
134+ }
135+
136+ @ Test
137+ void testRotateAllZeros () {
138+ // Test with all bits zero
139+ int value = 0x00000000 ;
140+ assertEquals (value , BitRotate .rotateLeft (value , 15 ));
141+ assertEquals (value , BitRotate .rotateRight (value , 19 ));
142+ }
143+
144+ // ===== Exception Tests =====
145+
146+ @ Test
147+ void testRotateLeftNegativeShift () {
148+ // Negative shifts should throw IllegalArgumentException
149+ Exception exception = assertThrows (IllegalArgumentException .class ,
150+ () -> BitRotate .rotateLeft (42 , -1 ));
151+ assertTrue (exception .getMessage ().contains ("negative" ));
152+ }
153+
154+ @ Test
155+ void testRotateRightNegativeShift () {
156+ // Negative shifts should throw IllegalArgumentException
157+ Exception exception = assertThrows (IllegalArgumentException .class ,
158+ () -> BitRotate .rotateRight (42 , -5 ));
159+ assertTrue (exception .getMessage ().contains ("negative" ));
160+ }
161+
162+ // ===== Complementary Operations Test =====
163+
164+ @ Test
165+ void testRotateLeftRightComposition () {
166+ // Rotating left then right by same amount should return original value
167+ int original = 0x12345678 ;
168+ int shift = 7 ;
169+
170+ int leftRotated = BitRotate .rotateLeft (original , shift );
171+ int restored = BitRotate .rotateRight (leftRotated , shift );
172+
173+ assertEquals (original , restored );
174+ }
175+
176+ @ Test
177+ void testRotateRightLeftComposition () {
178+ // Rotating right then left by same amount should return original value
179+ int original = 0x9ABCDEF0 ;
180+ int shift = 13 ;
181+
182+ int rightRotated = BitRotate .rotateRight (original , shift );
183+ int restored = BitRotate .rotateLeft (rightRotated , shift );
184+
185+ assertEquals (original , restored );
186+ }
187+
188+ @ Test
189+ void testRotateLeft31IsSameAsRotateRight1 () {
190+ // Rotating left by 31 should be same as rotating right by 1
191+ int value = 0x55555555 ;
192+ assertEquals (BitRotate .rotateLeft (value , 31 ), BitRotate .rotateRight (value , 1 ));
193+ }
194+ }
0 commit comments