@@ -200,6 +200,31 @@ pub fn bitReverseNumber(number: i64, width: i64) i64 {
200200 return result ;
201201}
202202
203+ /// Reorders numbers in slice using the bit reverse value of the slice indexes.
204+ /// The numbers [0, 1, 2, 3] would become [0, 2, 1, 3] because 0 = 0b00 reversed
205+ /// is 0b00 = 0, 1 = 0b01 reversed is 0b10 = 2, 2 = 0b10 reversed is 0b01 = 1
206+ /// and 3 = 0b11 reversed is 0b11 = 3.
207+ /// The caller owns the returned memory.
208+ pub fn bitReverseSlice (allocator : Allocator , numbers : []const i64 ) ! []const i64 {
209+ // Length of numbers must be a power of 2.
210+ if (! isPowerOfTwo (@intCast (numbers .len ))) {
211+ return error .LengthNotPowerOfTwo ;
212+ }
213+
214+ const n = numbers .len ;
215+ const log2_n = std .math .log2_int (usize , @intCast (n ));
216+
217+ const result = try allocator .alloc (i64 , n );
218+
219+ for (0.. n ) | i | {
220+ const reversed_i = bitReverseNumber (@intCast (i ), log2_n );
221+ const idx : usize = @intCast (reversed_i );
222+ result [i ] = numbers [idx ];
223+ }
224+
225+ return result ;
226+ }
227+
203228test "findRootOfUnity - core" {
204229 var n : i64 = undefined ;
205230 var m : i64 = undefined ;
@@ -454,3 +479,60 @@ test "bitReverseNumber" {
454479 try testing .expectEqual (expected_2 , result_2 );
455480 }
456481}
482+
483+ test "bitReverseSlice" {
484+ const allocator = testing .allocator ;
485+
486+ {
487+ const input = [_ ]i64 { 0 , 1 , 2 , 3 , 4 , 5 };
488+ const expected = error .LengthNotPowerOfTwo ;
489+
490+ const result = bitReverseSlice (allocator , & input );
491+ try testing .expectError (expected , result );
492+ }
493+
494+ {
495+ const input = [_ ]i64 { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 };
496+ const expected = [_ ]i64 { 0 , 4 , 2 , 6 , 1 , 5 , 3 , 7 };
497+
498+ const result = try bitReverseSlice (allocator , & input );
499+ defer allocator .free (result );
500+
501+ try testing .expectEqualSlices (i64 , & expected , result );
502+ }
503+
504+ {
505+ const input = [_ ]i64 { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 };
506+ const expected = [_ ]i64 { 0 , 8 , 4 , 12 , 2 , 10 , 6 , 14 , 1 , 9 , 5 , 13 , 3 , 11 , 7 , 15 };
507+
508+ const result = try bitReverseSlice (allocator , & input );
509+ defer allocator .free (result );
510+
511+ try testing .expectEqualSlices (i64 , & expected , result );
512+ }
513+
514+ {
515+ const input = [_ ]i64 { 0 , 1 , 4 , 5 };
516+ const expected = [_ ]i64 { 0 , 4 , 1 , 5 };
517+
518+ const result = try bitReverseSlice (allocator , & input );
519+ defer allocator .free (result );
520+
521+ try testing .expectEqualSlices (i64 , & expected , result );
522+ }
523+
524+ {
525+ const input = [_ ]i64 { 11 , 22 , 33 , 44 , 55 , 66 , 77 , 88 };
526+ const expected = input ;
527+
528+ const input_1 = input ;
529+ const result_1 = try bitReverseSlice (allocator , & input_1 );
530+ defer allocator .free (result_1 );
531+
532+ const input_2 = result_1 ;
533+ const result_2 = try bitReverseSlice (allocator , input_2 );
534+ defer allocator .free (result_2 );
535+
536+ try testing .expectEqualSlices (i64 , & expected , result_2 );
537+ }
538+ }
0 commit comments