Sunday, June 1, 2008

First post, space-efficient square root

The purpose of this blog is to collect all of my random embedded code snippets that may be useful ... most of this is targeted at Microchip PIC18 processors and their C18 compiler, but it should be pretty portable to other CPUs and build tools.

I'm going to do my best to credit any sources for the code here, if it is not entirely original. However, if there is an omission, please let me know and I will add the appropriate attributions. Thanks!

Our first example is a reasonably quick, but also very compact, square root function for floating point numbers. The goal here was to get 6-8 digits of accuracy without sacrificing much code space or ram, with less emphasis on execution time.

Code:
float rsqrt (float x) {
    // 9 bytes of local variables
    float out; // 32 bits, IEEE single format
    unsigned long xint; // 32 bits
    byte i; // 8 bits

    (*(unsigned long*)&x) &= 0x7FFFFFFF; // enforce positive #
    xint = 0x5f375a86 - ((*(unsigned long*)&x >> 1) & 0x7FFFFFFF); // initial approximation
    out = *(float*)&xint;
    for (i = 0; i < 5; i++)
        out = out * (1.5 - x*0.5*out*out); // Newton's method
    return out * x;
}


Using the 'magic number' for approximation was discussed here: http://www.codemaestro.com/reviews/9

Total space: 328 bytes = 164 instructions on PIC18F4550

No comments: