Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Is something like this what you are looking for? The following "PARITY16(u16)" preprocessor macro can be used as a literal constant in structure assignments, and it only evaluates the argument once.</p> <pre><code>/* parity.c * test code to test out bit-twiddling cleverness * 2013-05-12: David Cary started. */ // works for all 0...0xFFFF // and only evalutes u16 one time. #define PARITYodd33(u33) \ ( \ ((((((((((((((( \ (u33) \ &amp;0x555555555)*5)&gt;&gt;2) \ &amp;0x111111111)*0x11)&gt;&gt;4) \ &amp;0x101010101)*0x101)&gt;&gt;8) \ &amp;0x100010001)*0x10001)&gt;&gt;16) \ &amp;0x100000001)*0x100000001)&gt;&gt;32) \ &amp;1) #define PARITY16(u16) PARITYodd33(((unsigned long long)u16)*0x20001) // works for all 0...0xFFFF // but, alas, generates 16 instances of u16. #define PARITY_16(u16) (PARITY8((u16)&amp;0xff) ^ PARITY8((u16)&gt;&gt;8)) #define PARITY8(u8) (PARITY4((u8)&amp;0x0f) ^ PARITY4((u8)&gt;&gt;4)) #define PARITY4(u4) (PARITY2((u4)&amp;0x03) ^ PARITY2((u4)&gt;&gt;2)) #define PARITY2(u2) (PARITY1((u2)&amp;0x01) ^ PARITY1((u2)&gt;&gt;1)) #define PARITY1(u1) (u1) int message1[] = { 0x1234, 0x5678, PARITY16(0x1234^0x5678) }; int message2[] = { 0x1234, 0x5678, PARITY_16(0x1234^0x5678) }; #include &lt;stdio.h&gt; int main(void){ int errors = 0; int i=0; printf(" Testing parity ...\n"); printf(" 0x%x = message with PARITY16\n", message1[2] ); printf(" 0x%x = message with PARITY_16\n", message2[2] ); for(i=0; i&lt;0x10000; i++){ int left = PARITY_16(i); int right = PARITY16(i); if( left != right ){ printf(" 0x%x: (%d != %d)\n", i, left, right ); errors++; return 0; }; }; printf(" 0x%x errors detected. \n", errors ); } /* vim: set shiftwidth=4 expandtab ignorecase : */ </code></pre> <p>Much like the original code you posted, it pairs up bits and (in effect) calculates the XOR between each pair, then from the results it pairs up the bits again, halving the number of bits each time until only a single parity bit remains.</p> <h2>But is that really what you wanted ?</h2> <p>Many people <em>say</em> they are calculating "the parity" of a message. But in my experience, most of the time they are really generating a <a href="http://en.wikipedia.org/wiki/error_detection_and_correction" rel="nofollow noreferrer">error-detection code</a> bigger than a single parity bit -- a <a href="http://en.wikipedia.org/wiki/longitudinal_redundancy_check" rel="nofollow noreferrer">LRC</a>, or a <a href="http://en.wikipedia.org/wiki/cyclic_redundancy_check" rel="nofollow noreferrer">CRC</a>, or a <a href="http://en.wikipedia.org/wiki/Hamming_code" rel="nofollow noreferrer">Hamming code</a>, or etc.</p> <h2>further details</h2> <p>If the current system is compiling in a reasonable amount of time, and it's giving the correct answers, I would leave it alone. Refactoring "how the pre-processor generates some constant" will produce bit-for-bit identically the same runtime executable. I'd rather have easy-to-read source even if it takes a full second longer to compile.</p> <p>Many people use a language easier-to-read than the standard C preprocessor to generate C source code. See <a href="https://softwareengineering.stackexchange.com/questions/96211/what-is-a-faster-alternative-to-a-crc/96374">pycrc</a>, the <a href="http://www.massmind.org/techref/datafile/charsets.htm" rel="nofollow noreferrer">character set extractor</a>, <a href="https://stackoverflow.com/questions/4000678/using-python-to-generate-a-c-string-literal-of-json">"using Python to generate C"</a>, etc.</p> <p>If the current system is taking way too long to compile, rather than tweak the C preprocessor, I would be tempted to put that message, including the parity, in a separate ".h" file with hard-coded constants (rather than force the C pre-processor to calculate them every time), and "#include" that ".h" file in the ".c" file for the embedded system.</p> <p>Then I would make a completely separate program (perhaps in C or Python) that does the parity calculations and prints out the contents of that ".h" file as pre-calculated C source code, something like</p> <pre><code>print("int message[] = { 0x%x, 0x%x, 0x%x };\n", M[0], M[1], parity( M[0]^M[1] ) ); </code></pre> <p>and tweak my <a href="http://en.wikibooks.org/wiki/makefile" rel="nofollow noreferrer">MAKEFILE</a> to run that Python (or whatever) program to regenerate that ".h" file if, and only if, it is necessary.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload