Skip to content

Commit 0b6ff4c

Browse files
committed
Upgrade code to latest Zig version
1 parent 1d630b9 commit 0b6ff4c

File tree

2 files changed

+30
-28
lines changed

2 files changed

+30
-28
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
This Zig library reimplements and improves upon the [Bit Twiddling Hacks](https://graphics.stanford.edu/~seander/bithacks.html) snippets originally authored by Sean Eron Anderson and contributors.
44

5+
Most recently tested with Zig master version `0.12.0-dev.3161+377ecc6af`. Run tests with `zig test bithacks.zig`
6+
57
Improvements include:
68

79
* Comptime args are used to prune branches in certain cases where the caller can provide extra information about the input.
@@ -1716,4 +1718,4 @@ w = t | ((((t & -t) / (v & -v)) >> 1) - 1);
17161718

17171719
Thanks to Dario Sneidermanis of Argentina, who provided this on November 28, 2009.
17181720

1719-
[A Belorussian translation](http://webhostingrating.com/libs/bithacks-be) (provided by [Webhostingrating](http://webhostingrating.com/)) is available.
1721+
[A Belorussian translation](http://webhostingrating.com/libs/bithacks-be) (provided by [Webhostingrating](http://webhostingrating.com/)) is available.

bithacks.zig

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ pub fn isSignBitSet(val: anytype) bool {
4141
}
4242

4343
test "Compute the sign of an integer" {
44-
var cases = [5]i32{ std.math.minInt(i32), -1, 0, 1, std.math.maxInt(i32) };
45-
var expected = [5]bool{ true, true, false, false, false };
44+
const cases = [5]i32{ std.math.minInt(i32), -1, 0, 1, std.math.maxInt(i32) };
45+
const expected = [5]bool{ true, true, false, false, false };
4646
for (cases, 0..) |num, i| {
4747
try expect(isSignBitSet(num) == expected[i]);
4848
}
@@ -72,8 +72,8 @@ pub fn absFast(val: anytype) @TypeOf(val) {
7272
}
7373

7474
test "Compute the integer absolute value (abs) without branching" {
75-
var cases = [5]i32{ std.math.minInt(i32) + 1, -1, 0, 1, std.math.maxInt(i32) };
76-
var expected = [5]i32{ std.math.maxInt(i32), 1, 0, 1, std.math.maxInt(i32) };
75+
const cases = [5]i32{ std.math.minInt(i32) + 1, -1, 0, 1, std.math.maxInt(i32) };
76+
const expected = [5]i32{ std.math.maxInt(i32), 1, 0, 1, std.math.maxInt(i32) };
7777
for (cases, 0..) |num, i| {
7878
try expect(absFast(num) == expected[i]);
7979
}
@@ -275,7 +275,7 @@ test "Counting bits set, Brian Kernighan's way" {
275275
/// https://github.com/cryptocode/bithacks#counting-bits-set-in-14-24-or-32-bit-words-using-64-bit-instructions
276276
pub fn countBitsSetModulus(val: anytype) usize {
277277
const T = requireInt(@TypeOf(val));
278-
var bits_set: u64 = switch (@typeInfo(T).Int.bits) {
278+
const bits_set: u64 = switch (@typeInfo(T).Int.bits) {
279279
14 => (val * @as(u64, 0x200040008001) & @as(u64, 0x111111111111111)) % 0xf,
280280
24 => res: {
281281
var c: u64 = ((@as(u64, @intCast(val)) & 0xfff) * @as(u64, 0x1001001001001) & @as(u64, 0x84210842108421)) % 0x1f;
@@ -382,10 +382,10 @@ pub fn bitPosOfRank(val: u64, rank: u64) u64 {
382382
const ones = ~@as(u64, 0);
383383

384384
// Do a normal parallel bit count for a 64-bit integer, but store all intermediate steps:
385-
var a: u64 = val - ((val >> 1) & ones / 3);
386-
var b: u64 = (a & ones / 5) + ((a >> 2) & ones / 5);
387-
var c: u64 = (b +% (b >> 4)) & ones / 0x11;
388-
var d: u64 = (c +% (c >> 8)) & ones / 0x101;
385+
const a: u64 = val - ((val >> 1) & ones / 3);
386+
const b: u64 = (a & ones / 5) + ((a >> 2) & ones / 5);
387+
const c: u64 = (b +% (b >> 4)) & ones / 0x11;
388+
const d: u64 = (c +% (c >> 8)) & ones / 0x101;
389389
var t: u64 = (d >> 32) + (d >> 48);
390390
var r = rank;
391391

@@ -457,7 +457,7 @@ pub fn parityByLookupTable(val: anytype) bool {
457457
// For each row n in [0..15], if the n'th bit in the seed is 0, use the seed as the row,
458458
// otherwise use the inverted seed as the row.
459459
const seed: u16 = 0b0110100110010110;
460-
var parityTable = comptime val: {
460+
const parityTable = comptime val: {
461461
var table: [16]u16 = undefined;
462462
var row: usize = 0;
463463
while (row < 16) : (row += 1) {
@@ -620,7 +620,7 @@ pub fn swapBitsXor(pos1: usize, pos2: usize, consecutiveBits: usize, val: anytyp
620620
const T = requireInt(@TypeOf(val));
621621
const shiftType = std.math.Log2Int(T);
622622

623-
var x: T = ((val >> @as(shiftType, @intCast(pos1))) ^ (val >> @as(shiftType, @intCast(pos2)))) & ((@as(T, 1) << @as(shiftType, @intCast(consecutiveBits))) - 1);
623+
const x: T = ((val >> @as(shiftType, @intCast(pos1))) ^ (val >> @as(shiftType, @intCast(pos2)))) & ((@as(T, 1) << @as(shiftType, @intCast(consecutiveBits))) - 1);
624624
return val ^ ((x << @as(shiftType, @intCast(pos1))) | (x << @as(shiftType, @intCast(pos2))));
625625
}
626626

@@ -889,7 +889,7 @@ pub fn modPow2Minus1NoDiv(numerator: u32, shiftAmount: usize) u32 {
889889
const shiftType = std.math.Log2Int(u32);
890890
const s = shiftAmount;
891891
const d = (@as(u32, 1) << @as(shiftType, @intCast(shiftAmount))) - 1;
892-
var n = numerator;
892+
const n = numerator;
893893
var m: u32 = (n & M[s]) +% ((n >> @as(shiftType, @intCast(s))) & M[s]);
894894

895895
var q: usize = 0;
@@ -945,8 +945,8 @@ test "Find the log base 2 of an integer with the MSB N set in O(N) operations (t
945945
pub fn log2usingFloat(val: u32) u32 {
946946
const endian = @import("builtin").target.cpu.arch.endian();
947947
const little_endian: bool = switch (endian) {
948-
.Little => true,
949-
.Big => false,
948+
.little => true,
949+
.big => false,
950950
};
951951

952952
const U = extern union {
@@ -992,7 +992,7 @@ pub fn log2usingLookupTable(val: u32) u32 {
992992
break :val table;
993993
};
994994

995-
var tt: u32 = val >> 16;
995+
const tt: u32 = val >> 16;
996996
var t: u32 = undefined;
997997

998998
if (tt != 0) {
@@ -1133,8 +1133,8 @@ pub fn log2float32(val: f32, comptime supportSubnormals: bool) u32 {
11331133
f: f32,
11341134
u: u32,
11351135
};
1136-
var conv: U = .{ .f = val };
1137-
var x = conv.u;
1136+
const conv: U = .{ .f = val };
1137+
const x = conv.u;
11381138

11391139
if (supportSubnormals) {
11401140
// Build log table at compile time
@@ -1195,7 +1195,7 @@ pub fn log2float32pow(val: f32, r: u32) u32 {
11951195
f: f32,
11961196
u: u32,
11971197
};
1198-
var conv: U = .{ .f = val };
1198+
const conv: U = .{ .f = val };
11991199
return ((((conv.u -% 0x3f800000) >> @as(shiftType, @intCast(r))) +% 0x3f800000) >> 23) -% 127;
12001200
}
12011201

@@ -1237,7 +1237,7 @@ test "Count the consecutive zero bits (trailing) on the right linearly" {
12371237
/// Count the consecutive zero bits (trailing) on the right in parallel
12381238
/// https://github.com/cryptocode/bithacks#count-the-consecutive-zero-bits-trailing-on-the-right-in-parallel
12391239
pub fn countConsecutiveZeroBitsParallel(val: u32) usize {
1240-
var v: u32 = val & -%val;
1240+
const v: u32 = val & -%val;
12411241
var c: u32 = 32;
12421242

12431243
if (v != 0) c -%= 1;
@@ -1306,7 +1306,7 @@ pub fn countConsecutiveZeroBitsUsingFloat(val: u32) usize {
13061306
f: f32,
13071307
u: u32,
13081308
};
1309-
var conv: U = .{ .f = @as(f32, @floatFromInt(val & -%val)) };
1309+
const conv: U = .{ .f = @as(f32, @floatFromInt(val & -%val)) };
13101310
return (conv.u >> 23) - 0x7f;
13111311
}
13121312

@@ -1362,7 +1362,7 @@ pub fn roundToPow2ByFloat(val: u32) u32 {
13621362
f: f32,
13631363
u: u32,
13641364
};
1365-
var conv: U = .{ .f = @as(f32, @floatFromInt(val)) };
1365+
const conv: U = .{ .f = @as(f32, @floatFromInt(val)) };
13661366
const t = @as(u32, 1) << @as(shiftType, @intCast((conv.u >> 23) -% 0x7f));
13671367
return t << @intFromBool(t < val);
13681368
} else return 1;
@@ -1417,7 +1417,7 @@ pub fn interleaveBitsObvious(first: anytype, second: @TypeOf(first)) DoubledIntS
14171417
var res: T2 = 0;
14181418
var i: isize = 0;
14191419
while (i < bits) : (i += 1) {
1420-
var i_shift = @as(shiftType, @intCast(i));
1420+
const i_shift = @as(shiftType, @intCast(i));
14211421
res |= ((first & (@as(T2, 1) << i_shift)) << i_shift) | ((second & (@as(T2, 1) << i_shift)) << @as(shiftType, @intCast(i + 1)));
14221422
}
14231423

@@ -1489,8 +1489,8 @@ test "Interleave bits by table lookup" {
14891489
/// Interleave bits with 64-bit multiply
14901490
/// https://github.com/cryptocode/bithacks#interleave-bits-with-64-bit-multiply
14911491
pub fn interleaveBitsMul(first: u8, second: u8) u16 {
1492-
var x: u16 = first;
1493-
var y: u16 = second;
1492+
const x: u16 = first;
1493+
const y: u16 = second;
14941494

14951495
return @as(u16, @truncate(((((x *%
14961496
@as(u64, 0x0101010101010101)) & 0x8040201008040201) *%
@@ -1577,7 +1577,7 @@ pub fn countBytesLessThan(val: anytype, n: u8) usize {
15771577
const T = requireUnsignedInt(@TypeOf(val));
15781578

15791579
const maxBy255 = ~@as(T, 0) / 255;
1580-
var res = (((((maxBy255 *% @as(T, 127 +% n)) -%
1580+
const res = (((((maxBy255 *% @as(T, 127 +% n)) -%
15811581
(val & (maxBy255 *% 127))) & ~val) &
15821582
(maxBy255 *% 128)) / 128) % 255;
15831583
return @as(usize, @intCast(res));
@@ -1612,7 +1612,7 @@ pub fn countBytesGreaterThan(val: anytype, n: u8) usize {
16121612
const T = requireUnsignedInt(@TypeOf(val));
16131613

16141614
const maxBy255 = ~@as(T, 0) / 255;
1615-
var res = (((((val & (maxBy255 *% 127)) +%
1615+
const res = (((((val & (maxBy255 *% 127)) +%
16161616
(maxBy255 *% (127 -% n))) | val) &
16171617
(maxBy255 *% 128)) / 128) % 255;
16181618
return @as(usize, @intCast(res));
@@ -1678,7 +1678,7 @@ test "Determine if a word has a byte between m and n" {
16781678
/// https://github.com/cryptocode/bithacks#compute-the-lexicographically-next-bit-permutation
16791679
pub fn nextLexicographicPermutation(val: u32) u32 {
16801680
// Input's least significant 0 bits set to 1
1681-
var t = val | (val - 1);
1681+
const t = val | (val - 1);
16821682

16831683
// Set to 1 the most significant bit to change, set to 0 the least significant ones, and add the necessary 1 bits.
16841684
return (t + 1) | (((~t & -%~t) - 1) >> @as(u5, @intCast(@ctz(val) + 1)));

0 commit comments

Comments
 (0)