2.90 fpwr2

Problem:

You have been assigned the task of writing a C function to compute a floating-point representation of 2^x. You decide that the best way to do this is to directly construct the IEEE signle-precision representation of the result. When x is too small, your routine will return 0.0. When x is too big, it will return +∞. Fill in the blank portions of the code that follows to compute the correct result. Assume the function u2f returns a floating-point value having an identical bit representation as its unsigned argument.

#include <stdio.h>
#include <assert.h>
#include <math.h>

float u2f(unsigned u) {
    return *(float*) &u;
}

float fpwr2(int x) {
    /* Result exponent and fraction */
    unsigned exp, frac;
    unsigned u;

    /* E=1-bias=1-127=-126 n=23 */
    if (x < -149) {
        /* Too small. Return 0.0 */
        exp = 0;
        frac = 0;
    } else if (x < -126) {
        /* Denormalized result */
        exp = 0;
        frac = 1 << (unsigned) (x+149);
    } else if(x < 128){
        /* Normalized result */
        exp = x + 127;
        frac = 0;
    } else {
        /* Too big. Return +oo */
        exp = 0xFF;
        frac = 0;
    }

    /* Pack exp and frac into 32 bits */
    u = exp << 23 | frac;
    /* Return as float */
    return u2f(u);
}

int main() {
    assert(fpwr2(-150)==powf(2, -150));
    assert(fpwr2(-130)==powf(2, -130));
    assert(fpwr2(23)==powf(2, 23));
    assert(fpwr2(130)==powf(2, 130));
    return 0;
}

Last updated