C & C++ Tricks


5 minute read  • 

This section contains code snippets which I have acquired over time. Most of the code samples are in the C programming language. Just a couple require C++. Wherever possible, I have accredited the code with the respective authors. However, there are quite a few samples of which I have lost the original author’s details. In these cases I have left the snippets unaccredited. If you see a code snippet below, and you believe you know who originally published it, please drop me a line and I’ll update this page immediately.

Please send any comments or suggestions to:

Bit Twiddling

Is an integer number a power of 2?

#define ISPOW2(x) (x && !(x & (x-1)))

#define ISPOW2(n) (!( n & (n-1))

#define ISPOW2(x) ((~(~0U >> 1) | x) & x - 1)

Swap two integer numbers

int a, b;
...
a ^= b;
b ^= a;
a ^= b;

...
/* note that this is not portable */
a ^= b ^= a ^= b;

Detect if there is a zero byte in a 32bit word:

#define has_null_byte(x) (((x) - 0x01010101) & ~(x) & 0x80808080)

Divide an integer number by 15

unsigned div15(unsigned x)
{
    unsigned s,t;
    s = x >> 4;
    t = (x & 0xf) + s + 1;
    t += t >> 4;
    t = t + (t >> 8) >> 4) + s;
}
unsigned short div15(unsigned short x)
{
    unsigned t;
    t = x + 1;
    t += t << 4;
    t += t >> 8;
    t += t >> 16;
    return (unsigned short)(t >> 8);
}
long div15(long x)
{

    long s = (x >> 4) + (x >> 8);
    s += s >> 8;
    s += s >> 8;
    return s;
}

Bit Counting

Count the number of bits in an integer

int countbits(unsigned long num)
{
    int count;
    
    for(count = 0; num; num &= num - 1) count++;
    
    return count;
}

Using a lookup table:

int lookup[256];

void buildlookup(void)
{

    int i;
    for(i = 0; i < 256; i++)
    {
        unsigned char t = i;
        lookup[i] = 0;
        for(int j = 0; j < 8; j++)
        {
            if(t & 1) lookup[i]++;
            t >>= 1;
        }
    }
}

int countbits(int x)
{

    int count = lookup[x & 0xf] + 
            lookup[(x >> 8) & 0xf] +
            lookup[(x >> 16) & 0xf] +
            lookup[(x >> 24) & 0xf];


    return count;
}

Using some ingenious bit-twiddling

/* Bit counter by Ratko Tomic */
int countbits(long i)

{
      i = ((i & 0xAAAAAAAAL) >> 1) + (i & 0x55555555L);
      i = ((i & 0xCCCCCCCCL) >> 2) + (i & 0x33333333L);
      i = ((i & 0xF0F0F0F0L) >> 4) + (i & 0x0F0F0F0FL);
      i = ((i & 0xFF00FF00L) >> 8) + (i & 0x00FF00FFL);
      i = ((i & 0xFFFF0000L) >> 16) + (i & 0x0000FFFFL);
      return (int)i;
}

Number Rounding

Round an integer up to the nearsest alignment boundary.

n = (n + ALIGN - 1) - (n + ALIGN - 1) % ALIGN;
num = mod * ((num + mod - 1) / mod);

Assuming the mod is a power of 2, the rounding can take place using bitwise operators .

num = (num + mod - 1) & ~(mod - 1);

Base conversion

A FAST cast from float to long

inline long float2long(float d)
{
    #define MAGIC (((65536.0 * 65536.0 * 16.0) + 32768.0) * 65536.0)
    double dtemp = d + MAGIC;
    return (*(long *) &dtemp) - 0x80000000;
}

String & Memory routines

int memcmp2(void *mem1, void *mem2, size_t length)
{
    unsigned char *mptr1 = (unsigned char *)mem1;
    unsigned char *mptr2 = (unsigned char *)mem2;

    if(*mptr1++ != *mptr2++) return !0;

    unsigned char tempch = mem1[length-1];

    mem1[length-1] = ~mem2[length-1];

    /* do the comparison */
    while(*mptr1++ != *mptr2++);

    mem1[length-1] = tempch;

    if(mptr1 == (mem1 + length - 1))
        return 0;
    else
        return 1;
}

A weird memory copy, using Duff’s Device to check the loop termination 1 in every 8 iterations

switch(length & 0x7)
{
    do
    {
    case 7: *dest++ = *src++; 
    case 6: *dest++ = *src++;
    case 5: *dest++ = *src++;
    case 4: *dest++ = *src++;
    case 3: *dest++ = *src++;
    case 2: *dest++ = *src++;
    case 1: *dest++ = *src++;
    case 0:
    } while(0 <= length -= 8);
}

Miscallaneous

The weirdest C program? Requires 8086 family of processors.

int main[] = { 0xc3 };

Compiles as you type! Requies a unix tty terminal

#include "/dev/tty0"

Halt with a compile error if the target platform’s word size is not 32bits

int error_not_32bits[sizeof(int) == 4];

Calculate if a year is a leap year or not

/* 'The C Programming Language' by Kernigan & Richie */
int isleapyear(int year)
{
    return (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0);
}

Work out what the day of the week is for a given date

/* Tomohiko Sakamoto */
int dayofweek(int d, int m, int y)
{
    static int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
	 
    y -= m < 3;
    return ( y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}

A C program which source is the same as its output (format as one line)

char *s = "char *s = %c%s%c; 
main(){printf(s,34,s,34);}"; 
main(){printf(s,34,s,34);}

Calculate the value of PI

double PI = 4.0 * atan(1.0);

Calculate a random number in the range 0..N

bad: int r = rand() % N; /* not very random */
better: int r = rand() / (RAND_MAX / N + 1);

An even better method (i.e. more random) was suggested by Jerry Coffin - thanks!

int rand_lim(int limit) 
{
    /* return a random number between 0 and limit inclusive. */

    int divisor = RAND_MAX / (limit+1);
    int retval;

    do 
    {
        retval = rand() / divisor;
    } while (retval > limit);

    return retval;
}