On Sat, 5 Mar 2016 19:03:24 +0100, Bart (bartjun...@gmail.com) wrote
about "[fpc-pascal] Bitcounting" (in
<camye31xhge_egouaqk7hegk7by0steko5en11dkg3dmjyxd...@mail.gmail.com>):

> Does FreePascal have a routine for counting bits?
[snip]
> Surely this can be done better?

If you don't mind a bit of C, attached is what I use. It is blazingly
fast compared to examining each bit.

It uses ASCIIZ strings, but can easily be converted to Pascal and
AnsiStrings (or whatever). However, I'll leave that to you.
-- 
Regards,

Dave  [RLU #314465]
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
david.w.n...@googlemail.com (David W Noon)
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
#ifndef BIT_COUNT_H_INCLUDED
#define BIT_COUNT_H_INCLUDED

/* Functions to count how many 1-bits or 0-bits are in a buffer area.
 *
 * Copyright (C) 2015, David W. Noon.  All rights reserved.
 * This code is released under the Berkeley License.
 *
 */

#ifdef __cplusplus
#include <cstdlib>
#include <cstdint> /* Requires C++11 or later. */
#else
#include <stdlib.h>
#include <stdint.h> /* Requires C99 or later. */
#endif

/* Function to count the number of 1 bits in a buffer. */
static uint32_t count_ones(const void * buffer, size_t bytes_count)
{
	static const uint8_t ONES[256] = {
			0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
			1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
			1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
			2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
			1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
			2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
			2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
			3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
			1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
			2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
			2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
			3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
			2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
			3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
			3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
			4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 };
	uint32_t result = 0U;
#ifdef __cplusplus
	const uint8_t * byte_ptr = reinterpret_cast<const uint8_t *>(buffer);
#else
	const uint8_t * byte_ptr = (const uint8_t *) buffer;
#endif

	for (size_t ctr = bytes_count; ctr > 0; --ctr)
	{
		result += ONES[*byte_ptr];
		++byte_ptr;
	}

	return result;
}

/* Function to count the number of 0 bits in a buffer. */
static uint32_t count_zeroes(const void * buffer, size_t bytes_count)
{
	static const uint8_t ZEROES[256] = {
			8, 7, 7, 6, 7, 6, 6, 5, 7, 6, 6, 5, 6, 5, 5, 4,
			7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3,
			7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3,
			6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
			7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3,
			6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
			6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
			5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
			7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3,
			6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
			6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
			5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
			6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
			5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
			5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
			4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0 };
	uint32_t result = 0U;
#ifdef __cplusplus
	const uint8_t * byte_ptr = reinterpret_cast<const uint8_t *>(buffer);
#else
	const uint8_t * byte_ptr = (const uint8_t *) buffer;
#endif

	for (size_t ctr = bytes_count; ctr > 0; --ctr)
	{
		result += ZEROES[*byte_ptr];
		++byte_ptr;
	}

	return result;
}
#endif /* BIT_COUNT_H_INCLUDED */
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to