quantum-espresso/UtilXlib/fletcher32.c

43 lines
1.3 KiB
C

/*
fletcher32 check sum of an 16-byte integer array.
Taken verbatim from the optimized c version as reported in
https://en.wikipedia.org/wiki/Fletcher%27s_checksum#Optimizations
except for the fact that the data size (words) is not an argument
of the function but rather the address of its location is, as this
is what a fortran call passes as reference.
the type of words and ndata variables is also defined as uint32_t
instead of size_t because this is what fortran implicitely does.
SdG, September 3rd 2017
*/
#include <stdio.h>
#include <stdint.h>
#if defined(_WIN32)
#include <direct.h>
#else
#include <unistd.h>
#endif
uint32_t fletcher32( uint16_t const *data, uint32_t *ndata )
{
uint32_t sum1 = 0xffff, sum2 = 0xffff;
size_t tlen; uint32_t words = *ndata ;
while (words) {
tlen = ((words >= 359) ? 359 : words);
words -= tlen;
do {
sum2 += sum1 += *data++;
tlen--;
} while (tlen);
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
}
/* Second reduction step to reduce sums to 16 bits */
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
return (sum2 << 16) | sum1;
}