parity.zig (1385B) - Raw
1 //! parity - if number of bits set is even => 0, else => 1 2 //! - pariytXi2_generic for big and little endian 3 4 const std = @import("std"); 5 const builtin = @import("builtin"); 6 const common = @import("common.zig"); 7 8 pub const panic = common.panic; 9 10 comptime { 11 @export(&__paritysi2, .{ .name = "__paritysi2", .linkage = common.linkage, .visibility = common.visibility }); 12 @export(&__paritydi2, .{ .name = "__paritydi2", .linkage = common.linkage, .visibility = common.visibility }); 13 @export(&__parityti2, .{ .name = "__parityti2", .linkage = common.linkage, .visibility = common.visibility }); 14 } 15 16 pub fn __paritysi2(a: i32) callconv(.c) i32 { 17 return parityXi2(i32, a); 18 } 19 20 pub fn __paritydi2(a: i64) callconv(.c) i32 { 21 return parityXi2(i64, a); 22 } 23 24 pub fn __parityti2(a: i128) callconv(.c) i32 { 25 return parityXi2(i128, a); 26 } 27 28 inline fn parityXi2(comptime T: type, a: T) i32 { 29 var x: std.meta.Int(.unsigned, @typeInfo(T).int.bits) = @bitCast(a); 30 // Bit Twiddling Hacks: Compute parity in parallel 31 comptime var shift: u8 = @bitSizeOf(T) / 2; 32 inline while (shift > 2) { 33 x ^= x >> shift; 34 shift = shift >> 1; 35 } 36 x &= 0xf; 37 return (@as(u16, 0x6996) >> @intCast(x)) & 1; // optimization for >>2 and >>1 38 } 39 40 test { 41 _ = @import("paritysi2_test.zig"); 42 _ = @import("paritydi2_test.zig"); 43 _ = @import("parityti2_test.zig"); 44 }