calculating number of consecutive ones in a binary number using c# - c#

I want for the program to iterate through every possible binary number from 00000000 to 11111111 and I it to calculate the number of consecutive "runs" of ones.
Ex) 00000001 and 11100000 both count as a single runs of ones
00001010 and 11101110 both count as two runs of ones
The problem is, is that it ignores the AND mask part and I don't know why.
{
static void Main(string[] args)
{
//Start
int stuff = BitRunner8();
//Display
Console.Write(stuff);
Console.ReadKey();
}
public static int BitRunner8()
{
int uniRunOrNot = 0;
int uniRunCount = 0;
int uniRunTotal = 0;
//iterating from numbers 0 to 255
for (int x = 0; x < 255; x++)
{
//I use 128 as my AND mask because 128 is 10000000 in binary
for ( int uniMask = 128; uniMask != 0; uniMask >>= 1)
{
//This is the if statement that doesn't return true ever
if ((x & uniMask) != 0)
{
//If the and mask is true, and ther were no previous ones before it, add to the the uniRunCount
if (uniRunOrNot == 0)
{
//Total count of the runs
uniRunCount++;
}
// Making it so that if two consective ones are in a row, the 'if' statement right above would return false,
//so that it wouldn't add to the uniRunCount
uniRunOrNot++;
}
else
{
//add the total number of runs to uniRunTotal, and then reset both uniRunOrNot, and uniRunCount
uniRunTotal += uniRunCount;
uniRunOrNot = uniRunCount = 0;
}
}
}
//Divide the final amount by 256 total numbers
uniRunTotal /= 256;
return uniRunCount;
}
}

The problem is that your code ignores runs that include the least significant bit. Your code updates uniRunTotal only when it discovers a zero bit. When the least significant bit is non-zero, uniRunCount is never added to the total.
Add code after the loop to add uniRunCount to fix this problem.
You can also fix this issue by applying a sentinel strategy: count bits from the other end, and use nine bits instead of eight, because bit number nine is always zero:
for (int uniMask = 1; uniMask <= 256; uniMask <<= 1)

Related

'Summation of primes' takes too long [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I don't know why this takes forever for big numbers I'm trying to solve Problem 10 in Project Euler (https://projecteuler.net/problem=10). Can someone help me please?
It finds the first prime number and crosses all its factors, Then moves on to the next prime number and so on.
long sum=0;
int howmanyChecked = 1;
int target = 1000000;
int index = -1;
List<int> numbers = new List<int>(target);
List<bool> Isprime = new List<bool>(target);
for(int i=2;i<=target;i++)
{
numbers.Add(i);
Isprime.Add(true);
}
while (1 > 0)
{
index = Isprime.IndexOf(true, index + 1);
int Selected = numbers[index];
howmanyChecked++;
sum += Selected;
//Console.WriteLine($"selected prime number is {Selected}");
//int startfrom =numbers.IndexOf(Selected * Selected);
if (Selected >= target / 2)
{
Console.WriteLine("ss");
for(int i=index+1;i<target-1;i++)
{
if(Isprime[i]==true)
{
Console.WriteLine(numbers[i].ToString());
sum += numbers[i];
}
}
Console.WriteLine($"the sum of all prime nubers below {target} is {sum} tap to continue");
Console.ReadLine();
break;
}
else
{
for (int i = Selected; i * Selected <= target; i++)
{
int k = numbers.IndexOf(i * Selected);
if (k == -1)
break;
if (Isprime[k] == true)
{
Isprime[numbers.IndexOf(i * Selected)] = false;
howmanyChecked++;
//Console.WriteLine($"Checked number is {Selected * i} and we have counted {howmanyChecked} numbers");
}
}
}
if (howmanyChecked == target || index==target)
break;
}
Console.ReadLine();
Apply some straightforward optimizations:
list numbers should not be used because each number can be calculated based on an index
simplified initialization of Isprime.
For 1'000'000 got:
the sum of all prime numbers below 1000000 is 37548466742 tap to continue
long sum = 0;
int howmanyChecked = 1;
int target = 1000000;
int index = -1;
var Isprime = Enumerable.Repeat(true, target).ToArray();
while (1 > 0)
{
index = Array.IndexOf(Isprime, true, index + 1);
int Selected = index + 2;
howmanyChecked++;
sum += Selected;
//Console.WriteLine($"selected prime number is {Selected}");
//int startfrom =numbers.IndexOf(Selected * Selected);
if (Selected >= target / 2)
{
Console.WriteLine("ss");
for (int i = index + 1; i < target - 1; i++)
{
if (Isprime[i] == true)
{
Console.WriteLine(i + 2);
sum += i + 2;
}
}
Console.WriteLine($"the sum of all prime nubers below {target} is {sum} tap to continue");
Console.ReadLine();
break;
}
else
{
for (int i = Selected; i * Selected <= target; i++)
{
int k = i * Selected - 2;
if (k < 0)
break;
if (Isprime[k] == true)
{
Isprime[k] = false;
howmanyChecked++;
//Console.WriteLine($"Checked number is {Selected * i} and we have counted {howmanyChecked} numbers");
}
}
}
if (howmanyChecked == target || index == target)
break;
}
Console.ReadLine();
Do SoE (Sieve of Eratosthenes) up to n=2000000 in case you want to be memory efficient 2000000/16 = 62500 Bytes as you need just one bit per odd number). You can do the sum while filling SoE.
Your description is a SoE but you got too much code for a SoE ... my simple SoE solution for this is just 11 lines of formatted C++ code where half of it is variables declaration:
const DWORD N=2000000; // ~ 36 ms
const DWORD M=N>>1; // store only odd values from 3,5,7,...
char p[M]; // p[i] -> is 1+i+i prime? (factors map)
DWORD i,j,k,ss=0,n=0x10000000-N;
uint<2> s=2;
p[0]=0; for (i=1;i<M;i++) p[i]=1;
for(i=3,j=i>>1;i<N;i+=2,j++)
{
if (p[j]==1) { ss+=i; if (ss>=n) { s+=DWORD(ss); ss=0; }}
for(k=i+j;k<M;k+=i) p[k]=0;
} s+=DWORD(ss);
// s holds the answer 142913828922
where DWORD is unsigned 32bit int and uint<2> is 64bit unsigned int (as I am still on 32bit compiler that is why I do the sum so weirdly). As you can see you got maybe 3 times more code than necessary.
Using IsPrime without memoization is too slow but even with memoization can never beat SoE. see:
Prime numbers by Eratosthenes quicker sequential than concurrently?
btw. I got my Euler projects in single app where I do SoE up to 10^7 which creates a list of all primes up to 10^7 this takes 130 ms on my pretty old PC and that is then used for all the Euler problems related to primes (which speeds them up so the first 40 problems is finished below 1sec) which for this case (different solution code) takes 0.7 ms.
To avoid overflows sum on 64 bit arithmetics.
Also using dynamic lists without pre-allocation is slow. You do not need them anyway.
Try with this:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
int main()
{
int n,i,i1,imax;
long sumprime;
bool *prime5mod6,*prime1mod6;
n=2000000;
imax=(n-n%6)/6+1;
prime5mod6 = (bool *) calloc(imax+1,sizeof(bool));
prime1mod6 = (bool *) calloc(imax+1,sizeof(bool));
sumprime=5;
for(i=1;(6*i-1)*(6*i-1)<=n;i++){
if(prime5mod6[i]==false){
sumprime=sumprime+6*i-1;
for(i1=6*i*i;i1 <= imax+2*i;i1+=(6*i-1)){
if(i1<=imax)
prime5mod6[i1]=true;
prime1mod6[i1-2*i]=true;
}
}
if(prime1mod6[i]==false){
sumprime=sumprime+6*i+1;
for(i1 = 6*i*i;i1<=imax;i1+=(6*i+1)){
prime5mod6[i1]=true;
if(i1<=imax-2*i)
prime1mod6[i1+2*i]=true;
}
}
}
for(i1=i;i1<=imax-1;i1++){
if(prime5mod6[i1]==false)
sumprime=sumprime+6*i1-1;
if(prime1mod6[i1]==false)
sumprime=sumprime+6*i1+1;
}
if(prime5mod6[imax]==false && n%6==5)
sumprime=sumprime+6*imax-1;
if(prime1mod6[imax-1]==false && n%6==0)
sumprime=sumprime-(6*(imax-1)+1);
printf("\nPrime sum: %ld",sumprime);
free(prime5mod6);
free(prime1mod6);
return 0;
}

Efficient way to count the number of appearances of a digit in a number

I need to count the number of times a single digit (not 0) appears in a number (positive integer) of varying length.
The obvious solution is to convert the number to a string, the digit to a character and iterate over the string to count the number of times the character appears in the string.
static int CountDigitInString(string searchString, char digit)
{
int sum = 0;
for (int i = 0; i < searchString.Length; i++)
{
if (searchString[i] == digit)
sum++;
}
return sum;
}
The problem with this method, however, is that it is too slow for my purposes as I am running it many times.
public static void Run()
{
for (int i = 0; i < 1000000; i++)
{
CountDigitInString(i.ToString(), (char)j);
}
}
After I noted that the process took too much time, the CPU sampling profiler showed me that the problem was with the conversion to string.
So, how do I efficiently count the number of times a digit (single digit only, not a number) appears in a number (of any length)?
Here is more optimized version of #shaitibber solution. It replaces one division with multiplying and returns 1 for 0,0. It is about 20% faster.
static int CountDigitsInString2(int number, int digit)
{
int sum = 0;
do
{
int n2 = number / 10;
if (number - n2 * 10 == digit)
sum++;
number = n2;
} while (number != 0);
return sum;
}
And here is solution about three times faster than that (but does not work for 0 digit, which is not required). It precalculates results for numbers 0..9999.
private static int[][] cache = new int[10][];
private const int cacheSize = 10000;//or 100000
private static int[] initCache(int digit)
{
var ca = cache[digit] = new int[cacheSize];
for (int i = 0; i < ca.Length; ++i)
{
ca[i] = CountDigitsInString2(i, digit);
}
return ca;
}
static int CountDigitsInString3(int number, int digit)
{
var ca = cache[digit] ?? initCache(digit);
int sum = 0;
while (number != 0)
{
int n2 = number / cacheSize;
sum += ca[number - n2 * cacheSize];
number = n2;
};
return sum;
}
I found a way which turned out to be about 3 times as fast on average (checked using a Stopwatch):
static int CountDigitsInString(int number, int digit)
{
int sum = 0;
while (number != 0)
{
if (number % 10 == digit)
sum++;
number /= 10;
}
return sum;
}
EDIT:
I found a way which is over 4 times as fast as the one above. Before I start, note that this solution is valid only for cases in which you are counting appearances of a digit in consecutive numbers.
It occurred to me that if you counted the number of times the digit "d" appeared in a number "A", then you don't neccessarily have to recount the number of times "d" appears in "A + 1" to know what it is.
For example, if I know that the digit 3 appears 4 times in the number 35312336, I can know for a fact that it will still appear 4 times in the next consecutive number 35312337, without actually counting.
The reason I can do this is that the count would only change in one of three cases:
1) When the last digit of "A - 1" was a 9, "A" can change entirely due to numbers being carried over. This is the only case in which we actually have to count (although you could, theoretically, optimize this further by checking the numbers carried over to see if they affect the total but this strikes me as overly complicated).
2) When the last digit of "A - 1" was "d - 1", we know that the number of times "d" appears in "A" has increased by one.
3) When the last digit of "A - 1" was "d", we know that the number of times "d" appears in "A" has decreased by one.
This means that you only have to count the appearances of "d" in "A" using arithmetical operations in one out of 10 cases!
public static void Run()
{
int digit = 1;
int count = 0;
for (int i = 0; i < 100000; i++)
{
int previousLastDigit = (i - 1) % 10;
if (previousLastDigit == (digit - 1))
count++;
else if (previousLastDigit == 9)
count = CountDigitsInString(i, digit);
else if (previousLastDigit == digit)
count--;
Console.WriteLine(digit + " appears " + count + " times in the number " + i);
}
}
The CountDigitsInString function is the one above.
Here is a little snip with LINQ to give you another way to do it (didn't ran a stopwatch)
var number = 11334511;
var digit = 1;
var digitAsChar = Convert.ToChar(digit.ToString().ToLower());
// Occurence will be 4
var occurence = number.ToString().ToLower().Count(s => s == digitAsChar);
I suggest you use LINQ on string.
Source: https://msdn.microsoft.com/en-us/library/mt693025.aspx
static int CountDigitInString(string number, char digit)
{
int count = number.Count(ns => ns == digit);
return count;
}

C#: How should I go about shuffling contents of an array?

I have an array of integers called cards[52]. Each element contains an integer that represents a card (cards[0] = 5 would represent the 6 of clubs for example).
This is how I shuffled the array. It works, but I am getting repeats.
private void shuffleCards()
{
for (int i = 0; i < cards.Length; i++)
{
int randIndex = r.Next(0, 52);
int origCard = cards[i];
cards[i] = cards[randIndex];
cards[randIndex] = origCard;
}
}
r is the Random variable I initialized in the beginning of the program.
When testing the program, I noticed I would get the same card 2 or 3 times. Obviously I cannot get repeats, they all must be different. I can't see in any way how this method gives me repeats.
How can I shuffle this array without any repeats? Thanks.
EDIT
Okay, turns out the shuffle function wasn't the problem. It is the deal() function that is causing the problem.
private void deal()
{
for (int i = 0; i < 26; i++)
{
userCards[i] = cards[i];
setUserValue(); //ignore this
}
for (int i = 26; i < 52; i++)
{
opponentCards[i - 26] = cards[i];
setOpponentValue(); //ignore this
}
}
I know for sure it isn't the shuffle function. I printed the results of all the cards to a text file and saw no iterations. However, when the cards are dealt to the user and the opponent, that's when all the iterations occur. Any advice?
There is very simple algorithm known as Fisher Yates shuffling algorithm which does the shuffling in O(n) time and O(1) space complexity.
Use a random function that generates a random index from the given set and replace the random element generated with the last index. Decrement last index and continue like this for the rest of elements.
Let the array of size n be : arr[n]
void randomize ( int arr[], int n )
{
// Use a different seed value so that we don't get same
// result each time we run this program
srand ( time(NULL) );
// Start from the last element and swap one by one. We don't
// need to run for the first element that's why i > 0
for (int i = n-1; i > 0; i--)
{
// Pick a random index from 0 to i
int j = rand() % (i+1);
// Swap arr[i] with the element at random index
swap(&arr[i], &arr[j]);
}
}
Source : Algorithm

C# Parity Bits from a Binary Number [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to add even parity bit on 7-bit binary number
This is my new code which converts a 7-bit binary number to an 8-bit with even parity. However it does not work. When I type in 0101010 for example, it says the number with even parity is 147. Could you help, showing me what is wrong please?
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Please enter a 7-bit binary number:");
int a = Convert.ToInt32(Console.ReadLine());
byte[] numberAsByte = new byte[] { (byte)a };
System.Collections.BitArray bits = new System.Collections.BitArray(numberAsByte);
a = a << 1;
int count = 0;
for (int i = 0; i < 8; i++)
{
if (bits[i])
{
count++;
}
if (count % 2 == 1)
{
bits[7] = true;
}
bits.CopyTo(numberAsByte, 0);
a = numberAsByte[0];
Console.WriteLine("The number with an even parity bit is:");
Console.Write(a);
Console.ReadLine();
}
}
}
Use int.TryParse() on what you got from Console.ReadLine(). You then need to check that the number is between 0 and 127 to ensure it uses only 7 bits. You then need to count the number of 1s in the binary representation of the number. And add 128 to the number to set the parity bit, depending whether you specified odd or even parity.
Counting 1s is your real homework assignment.
By using the BitArray class you can write
int a = Convert.ToInt32(Console.ReadLine());
byte[] numberAsByte = new byte[] { (byte)a };
BitArray bits = new BitArray(numberAsByte);
This converts the single bits of your byte to a BitArray, which represents an array of Booleans that can be handled in a easy way. Note that the constructor of BitArray accepts an array of bytes. Since we have only one byte, we have to pass it a byte array of length 1 containing this single byte (numberAsByte).
Now let us count the bits that are set.
int count = 0;
for (int i = 0; i < 8; i++) {
if (bits[i]) {
count++;
}
}
Note that we simply test for a bit with bits[i], which yields a Boolean value. The test bits[i] == true as being perfectly legal and correct yields the same result but is unnecessarily complicated. The if statement does not require a comparison. All it wants is a Boolean value.
This calculates an odd parity bit.
if (count % 2 == 1) { // Odd number of bits
bits[7] = true; // Set the left most bit as parity bit for even parity.
}
The % operator is the modulo operator. It yields the rest of an integer division. x % 2 yields 0 if x is even. If you want an odd parity bit, you can test count % 2 == 0 instead.
BitArray has a CopyTo method which converts our bits back to an array of bytes (containing only one byte in our case).
bits.CopyTo(numberAsByte, 0);
a = numberAsByte[0];
numberAsByte[0] contains our number with a parity bit.
If you want the parity bit on the right side, then you will have to shift the number to the left by one bit first.
int a = Convert.ToInt32(Console.ReadLine());
a = a << 1;
// Do the parity bit calculation as above and, if necessary
// set the right most bit as parity bit.
bits[0] = true;
According to wikipedia there are two variation of parity bits, so I implemented parameter to select the one you need. It supports user input up to 63 bits, i'm leaving implementation of validation code to you.
ulong GetNumberParity(string input, bool isEvenParity)
{
ulong tmp = Convert.ToUInt64(input, 2);
ulong c = 0;
for (int i = 0; i < 64; i++) c += tmp >> i & 1;
if(isEvenParity)
return Convert.ToUInt64((c % 2 != 0 ? "1" : "0") + input, 2);
else
return Convert.ToUInt64((c % 2 == 0? "1" : "0") + input, 2);
}

Counting common bits in a sequence of unsigned longs

I am looking for a faster algorithm than the below for the following. Given a sequence of 64-bit unsigned integers, return a count of the number of times each of the sixty-four bits is set in the sequence.
Example:
4608 = 0000000000000000000000000000000000000000000000000001001000000000
4097 = 0000000000000000000000000000000000000000000000000001000000000001
2048 = 0000000000000000000000000000000000000000000000000000100000000000
counts 0000000000000000000000000000000000000000000000000002101000000001
Example:
2560 = 0000000000000000000000000000000000000000000000000000101000000000
530 = 0000000000000000000000000000000000000000000000000000001000010010
512 = 0000000000000000000000000000000000000000000000000000001000000000
counts 0000000000000000000000000000000000000000000000000000103000010010
Currently I am using a rather obvious and naive approach:
static int bits = sizeof(ulong) * 8;
public static int[] CommonBits(params ulong[] values) {
int[] counts = new int[bits];
int length = values.Length;
for (int i = 0; i < length; i++) {
ulong value = values[i];
for (int j = 0; j < bits && value != 0; j++, value = value >> 1) {
counts[j] += (int)(value & 1UL);
}
}
return counts;
}
A small speed improvement might be achieved by first OR'ing the integers together, then using the result to determine which bits you need to check. You would still have to iterate over each bit, but only once over bits where there are no 1s, rather than values.Length times.
I'll direct you to the classical: Bit Twiddling Hacks, but your goal seems slightly different than just typical counting (i.e. your 'counts' variable is in a really weird format), but maybe it'll be useful.
The best I can do here is just get silly with it and unroll the inner-loop... seems to have cut the performance in half (roughly 4 seconds as opposed to the 8 in yours to process 100 ulongs 100,000 times)... I used a qick command-line app to generate the following code:
for (int i = 0; i < length; i++)
{
ulong value = values[i];
if (0ul != (value & 1ul)) counts[0]++;
if (0ul != (value & 2ul)) counts[1]++;
if (0ul != (value & 4ul)) counts[2]++;
//etc...
if (0ul != (value & 4611686018427387904ul)) counts[62]++;
if (0ul != (value & 9223372036854775808ul)) counts[63]++;
}
that was the best I can do... As per my comment, you'll waste some amount (I know not how much) running this in a 32-bit environment. If your that concerned over performance it may benefit you to first convert the data to uint.
Tough problem... may even benefit you to marshal it into C++ but that entirely depends on your application. Sorry I couldn't be more help, maybe someone else will see something I missed.
Update, a few more profiler sessions showing a steady 36% improvement. shrug I tried.
Ok let me try again :D
change each byte in 64 bit integer into 64 bit integer by shifting each bit by n*8 in lef
for instance
10110101 -> 0000000100000000000000010000000100000000000000010000000000000001
(use the lookup table for that translation)
Then just sum everything togeter in right way and you got array of unsigned chars whit integers.
You have to make 8*(number of 64bit integers) sumations
Code in c
//LOOKTABLE IS EXTERNAL and has is int64[256] ;
unsigned char* bitcounts(int64* int64array,int len)
{
int64* array64;
int64 tmp;
unsigned char* inputchararray;
array64=(int64*)malloc(64);
inputchararray=(unsigned char*)input64array;
for(int i=0;i<8;i++) array64[i]=0; //set to 0
for(int j=0;j<len;j++)
{
tmp=int64array[j];
for(int i=7;tmp;i--)
{
array64[i]+=LOOKUPTABLE[tmp&0xFF];
tmp=tmp>>8;
}
}
return (unsigned char*)array64;
}
This redcuce speed compared to naive implemetaton by factor 8, becuase it couts 8 bit at each time.
EDIT:
I fixed code to do faster break on smaller integers, but I am still unsure about endianess
And this works only on up to 256 inputs, becuase it uses unsigned char to store data in. If you have longer input string, you can change this code to hold up to 2^16 bitcounts and decrease spped by 2
const unsigned int BYTESPERVALUE = 64 / 8;
unsigned int bcount[BYTESPERVALUE][256];
memset(bcount, 0, sizeof bcount);
for (int i = values.length; --i >= 0; )
for (int j = BYTESPERVALUE ; --j >= 0; ) {
const unsigned int jth_byte = (values[i] >> (j * 8)) & 0xff;
bcount[j][jth_byte]++; // count byte value (0..255) instances
}
unsigned int count[64];
memset(count, 0, sizeof count);
for (int i = BYTESPERVALUE; --i >= 0; )
for (int j = 256; --j >= 0; ) // check each byte value instance
for (int k = 8; --k >= 0; ) // for each bit in a given byte
if (j & (1 << k)) // if bit was set, then add its count
count[i * 8 + k] += bcount[i][j];
Another approach that might be profitable, would be to build an array of 256 elements,
which encodes the actions that you need to take in incrementing the count array.
Here is a sample for a 4 element table, which does 2 bits instead of 8 bits.
int bitToSubscript[4][3] =
{
{0}, // No Bits set
{1,0}, // Bit 0 set
{1,1}, // Bit 1 set
{2,0,1} // Bit 0 and bit 1 set.
}
The algorithm then degenerates to:
pick the 2 right hand bits off of the number.
Use that as a small integer to index into the bitToSubscriptArray.
In that array, pull off the first integer. That is the number of elements in the count array, that you need to increment.
Based on that count, Iterate through the remainder of the row, incrementing count, based on the subscript you pull out of the bitToSubscript array.
Once that loop is done, shift your original number two bits to the right.... Rinse Repeat as needed.
Now there is one issue I ignored, in that description. The actual subscripts are relative. You need to keep track of where you are in the count array. Every time you loop, you add two to an offset. To That offset, you add the relative subscript from the bitToSubscript array.
It should be possible to scale up to the size you want, based on this small example. I would think that another program could be used, to generate the source code for the bitToSubscript array, so that it can be simply hard coded in your program.
There are other variation on this scheme, but I would expect it to run faster on average than anything that does it one bit at a time.
Good Hunting.
Evil.
I believe this should give a nice speed improvement:
const ulong mask = 0x1111111111111111;
public static int[] CommonBits(params ulong[] values)
{
int[] counts = new int[64];
ulong accum0 = 0, accum1 = 0, accum2 = 0, accum3 = 0;
int i = 0;
foreach( ulong v in values ) {
if (i == 15) {
for( int j = 0; j < 64; j += 4 ) {
counts[j] += ((int)accum0) & 15;
counts[j+1] += ((int)accum1) & 15;
counts[j+2] += ((int)accum2) & 15;
counts[j+3] += ((int)accum3) & 15;
accum0 >>= 4;
accum1 >>= 4;
accum2 >>= 4;
accum3 >>= 4;
}
i = 0;
}
accum0 += (v) & mask;
accum1 += (v >> 1) & mask;
accum2 += (v >> 2) & mask;
accum3 += (v >> 3) & mask;
i++;
}
for( int j = 0; j < 64; j += 4 ) {
counts[j] += ((int)accum0) & 15;
counts[j+1] += ((int)accum1) & 15;
counts[j+2] += ((int)accum2) & 15;
counts[j+3] += ((int)accum3) & 15;
accum0 >>= 4;
accum1 >>= 4;
accum2 >>= 4;
accum3 >>= 4;
}
return counts;
}
Demo: http://ideone.com/eNn4O (needs more test cases)
http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive
One of them
unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; c++)
{
v &= v - 1; // clear the least significant bit set
}
Keep in mind, that complexity of this method is aprox O(log2(n)) where n is the number to count bits in, so for 10 binary it need only 2 loops
You should probably take the metod for counting 32 bits whit 64 bit arithmetics and applying it on each half of word, what would take by 2*15 + 4 instructions
// option 3, for at most 32-bit values in v:
c = ((v & 0xfff) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f;
c += (((v & 0xfff000) >> 12) * 0x1001001001001ULL & 0x84210842108421ULL) %
0x1f;
c += ((v >> 24) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f;
If you have sse4,3 capable processor you can use POPCNT instruction.
http://en.wikipedia.org/wiki/SSE4

Categories

Resources