Skip to content

Commit f6a41b4

Browse files
committed
Added solution for determining the parity of a binary integral value.
1 parent f8cac7f commit f6a41b4

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
3+
/**
4+
* The parity of a binary word is 1 if the number of 1s in the word is odd; othersie it is 0.
5+
* A common use case for parity checking is error detection, especially when transmitting data.
6+
* https://en.wikipedia.org/wiki/Parity_bit
7+
*/
8+
9+
#include <climits> // CHAR_BIT
10+
#include <type_traits>
11+
12+
/**
13+
* Determines the parity of a given binary integer value.
14+
* Returns true if Parity is 1, or false if Parity is 0.
15+
*
16+
* Parity is determined by repeatedly performing an XOR operation on the upper half of the binary
17+
* value against the lower half until we're left with a single bit that represents the parity.
18+
*
19+
* Note that the runtime speed of this can be improved (up to ~1.5x) by specializing the function
20+
* on input type and unwinding the loop.
21+
*/
22+
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
23+
bool parity(T value)
24+
{
25+
short bits = CHAR_BIT * sizeof(T);
26+
while ((bits /= 2) >= 1)
27+
{
28+
value ^= value >> bits;
29+
}
30+
return value & 0b1;
31+
}

test/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,22 @@ catch_discover_tests(
4040
.xml
4141
)
4242

43+
add_executable(parity_tests "bitwise/parity_tests.cpp")
44+
target_link_libraries(parity_tests PRIVATE project_options project_warnings catch_main)
45+
catch_discover_tests(
46+
parity_tests
47+
TEST_PREFIX
48+
"parity."
49+
REPORTER
50+
xml
51+
OUTPUT_DIR
52+
.
53+
OUTPUT_PREFIX
54+
"parity."
55+
OUTPUT_SUFFIX
56+
.xml
57+
)
58+
4359
add_executable(has_function_tests "conditions/has_function_tests.cpp")
4460
target_link_libraries(has_function_tests PRIVATE project_options project_warnings catch_main)
4561
catch_discover_tests(

test/bitwise/parity_tests.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include "code_library/bitwise/parity.hpp"
2+
3+
#include <catch2/catch.hpp>
4+
5+
TEST_CASE("Parity of integral can be determined", "[parity]")
6+
{
7+
SECTION("Parity of uint32_t")
8+
{
9+
uint32_t value1 = 0b1000'1000'1000'1000'1000'1000'1000'1000;
10+
uint32_t value2 = 0b1000'0000'1000'1000'1000'1000'1000'1000;
11+
uint32_t value3 = 0b1111'1111'1111'1111'1111'1111'1111'1111;
12+
REQUIRE(!parity(value1));
13+
REQUIRE(parity(value2));
14+
REQUIRE(!parity(value3));
15+
}
16+
17+
SECTION("Parity of an char8_t")
18+
{
19+
char8_t value1 = 0b1000'1000;
20+
char8_t value2 = 0b1000'0000;
21+
char8_t value3 = 0b1111'1111;
22+
REQUIRE(!parity(value1));
23+
REQUIRE(parity(value2));
24+
REQUIRE(!parity(value3));
25+
}
26+
27+
SECTION("Parity of an int64_t")
28+
{
29+
int64_t value1 = 0b100'1000'1000'1000'1000'1000'1000'1000'1000'1000'1000'1000'1000'1000'1000'1000;
30+
int64_t value2 = 0b100'0000'1000'1000'1000'1000'1000'1000'1000'1000'1000'1000'1000'1000'1000'1000;
31+
int64_t value3 = 0b111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111;
32+
REQUIRE(!parity(value1));
33+
REQUIRE(parity(value2));
34+
REQUIRE(parity(value3));
35+
}
36+
}

0 commit comments

Comments
 (0)