HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Implementing checksum add without carry in C

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withoutcarrychecksumimplementingadd

Problem

I need to write a function in C which performs a checksum using the rule "add without carry". As I understand it, the "add without carry" concept is equivalent to the bitxor operator and given that the bitxor operation is associative and commutative, I am relying on that to perform the calculation. Below is my function. Note that the input is in decimal format and the checksum is of the binary digits with final output being in decimal format.

UCHAR checksumAddWoCarry(int num, ...)
{
    va_list valist;  /* List of variable arguments */
    UINT arg1, arg2; /* The first two arguments from the va_list */
    int i;           /* Iterator */
    UINT result;     /* Storage for returned result */

    va_start(valist, num); /* Start the usage of the list */

    arg1 = va_arg(valist,UINT); /* Pull out the first two variable arguments */
    arg2 = va_arg(valist,UINT);
    result = arg1 ^ arg2;
    if (num > 2) {
        for (i = 2; i < num; i++) {
            result ^= va_arg(valist,UINT);
        }
    }

    va_end(valist);

    return (UCHAR)result;
}


An example call would be

result = checksumAddWoCarry(3, 4,5,6);


where I expect that result is 7.

I would like an answer to two related questions.

  • Is my logic for the implementation correct? Specifically in


regards to my use of the bitxor operator to perform the checksum?

  • I want to know, aside from the logic of the implementation, if my


method is a good one. Are there any gotchas I could run into? Is
there a better/faster way?

Solution

It appears code is simply exclusive or-ing the arguments. Sounds like a "add without carry".

-
"Is my logic for the implementation correct?"

Appears correct except the range of acceptable values is not clearly stated.

-
Gotcha 1. What is UINT? If UINT is narrower than int/unsigned, the arguments will be widened and va_arg(valist,UINT); is problematic. Recommend unsigned instead.

-
Gotcha 2. arg1 = va_arg(valist,UINT); arg2 = va_arg(valist,UINT); Only makes sense if n it at least 1 or 2. Should test for that first.

-
`if (num > 2) {
for (i = 2; i

-
Simplify

va_list valist;
va_start(valist, num);
unsigned result = 0;
while (num-- > 0) {
  result ^= va_arg(valist, unsigned);
}
va_end(valist);
return result;

Code Snippets

va_list valist;
va_start(valist, num);
unsigned result = 0;
while (num-- > 0) {
  result ^= va_arg(valist, unsigned);
}
va_end(valist);
return result;

Context

StackExchange Code Review Q#135529, answer score: 5

Revisions (0)

No revisions yet.