0

I am using anonymous structs in unions to get a%b quickly.

Do you know any other way to get a%b without using powers of 2 for b.

include list:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

and declaration of unions:

//C99
//my first program to test rand() for any periodicity
union //for array indexing without modulus operator
{
unsigned int counter; //32 bit on my computer
struct
{
    unsigned int lsb:16; //16 bit 
    unsigned int msb:16; //16 bit   
};
struct 
{
    unsigned int bit[32];
};
} modulo;

union // for rand()%256
{
unsigned int randoom; //from rand() 
struct
{
unsigned int lsb:5;//equivalent to rand()%32 without any calculations
unsigned int msb:27;
};
}random_modulus;

and here the main function:

int main()
{
srand(time(0));

modulo.counter=0;//init of for-loop counter

// i am takin (counter%65536) for my array index which is modulus.lsb
unsigned int array_1[65536]; 
float array_mean=0,delta_square=0;
clock_t clock_refe;


//taking counter%65536 using lsb (2x faster)
clock_refe=clock();
for(;modulo.counter<1000000000;modulo.counter++)
{
// i need accumulated randoms for later use for some std. dev. thing.
random_modulus.randoom=rand();
array_1[modulo.lsb]+=random_modulus.lsb;
}

//getting average clock cycles
for(int i=0;i<65536;i++)
{
array_mean+=array_1[i];

}
array_mean/=65536.0f;

//getting square of deltas
float array_2[65536];

for(int i=0;i<65536;i++)
{
array_2[i]=(array_1[i]-array_mean)*(array_1[i]-array_mean); 
}


//horizontal histogram for resoluton of 20 elements
for(int i=0;i<65536;i+=(65536)/20)
{


for(int j=0;j<(array_2[i]*0.01);j++)
{

    printf("*");
}
printf("\n");
}

//calculations continue .....
return 0;

}

Pre-calculated values in some array maybe? But if i use the % calc part for only once, this is same. Can you give some book references about bitwise operations manuals?

timrau
  • 22,578
  • 4
  • 51
  • 64
huseyin tugrul buyukisik
  • 11,469
  • 4
  • 45
  • 97
  • 2
    The compiler optimises a modulo by a power of two to a bitmask, the same as it gets the bit-field. – Daniel Fischer Jul 13 '12 at 08:18
  • ok. but if i want to use a%35, can i use union and some addition and multiplication to get the result? – huseyin tugrul buyukisik Jul 13 '12 at 08:23
  • 1
    No. At least, not easily. A union with a struct of bit-fields only works for power-of-two moduli. For anything else, you have to calculate. If the modulus is a compile-time constant, the compiler should optimise it to a multiplication+bitshift+multiplication+subtraction if that's faster on the platform. – Daniel Fischer Jul 13 '12 at 08:29

1 Answers1

1

Bitwise operations are the most portable method in this case. Here's some example functions; they are written for readability, but can be easily made faster:

int lsb(int input) {
    int mask = 0x00FF; // 0x00FF is 0000000011111111 in binary
    return input & mask;
}

int msb(int input) {
    int mask = 0xFF00; // 0xFF00 is 1111111100000000 in binary
    return (input & mask) >> 8;
}

In general, mask the bits you want with &, and then align them to the right with >>. K&R 2nd edition (The C Programming Language by Brian Kernighan & Dennis Ritchie) has information on just about every C topic, including bitmasks.

If you want a % b where b is not a power of 2, the native % operator is the fastest way (in modern compilers it's as fast as the bitwise operations, even when b is a power of two). Bitwise operations are useful in other contexts, though.

Ilmo Euro
  • 4,925
  • 1
  • 27
  • 29
  • i saw quake-3 arena's inverse sqrt for an example. The book did you mention can explain that? – huseyin tugrul buyukisik Jul 13 '12 at 08:36
  • 1
    @tuğrulbüyükışık It gives the tools for explaining that; language-wise, the Q3 sqrt contains only standard C, explained in K&R. The real puzzle is in the mathematics, though. – Ilmo Euro Jul 13 '12 at 08:39
  • 1
    @tuğrulbüyükışık http://www.codemaestro.com/reviews/9 here's some additional info on the topic. – Ilmo Euro Jul 13 '12 at 08:41
  • its like using Gauss Seidel against Gauss-Jordan for 1000x1000 linear system coefficient matrix. thanks – huseyin tugrul buyukisik Jul 13 '12 at 08:54
  • 1
    One exception is when you have to calculate `pow(a, b) % n`, when `pow(a, b)` is very large; there's different methods for that. See http://stackoverflow.com/questions/8496182/calculating-powa-b-mod-n – Ilmo Euro Jul 13 '12 at 09:08