JCD February 2016

floating point multiplication using bit manipulation

I'm trying to solve a problem where I need to return the bit-level equivalent of an unsigned floating point number times 4.

So far I've been exploring other answers and found one that was pretty similar to mine, but also didn't work. There really wasn't an explanation given so I'm trying to understand what I am getting wrong when I run the test cases.

When I test my problems I get

33554432[0x2000000].

But I should be

25165824[0x1800000]

So far my code is

unsigned a = (uf >> 0x17) & 0xFF;
unsigned b = uf & 0x80000000;
unsigned c = uf & 0x007FFFFF;
if (a == 0xFF || (a == 0x0 && c == 0x0))  
    return uf;
if (a) {
    a <<= 0x2;
} else if (c == 0x7FFFFF) {
    c >>= 0x2;
    a <<= 0x2;
} else {
    c <<= 0x2;
}

return (a<<0x17|b|c);

Any advice?

Answers


zwol February 2016

Unless you are actually writing a software floating-point emulator (in which case you need more help than we can give you), you should let the compiler handle this:

#include <stdint.h>
#include <assert.h>

static_assert(sizeof(float) == sizeof(uint32_t));

uint32_t multiply_by_4_as_float(uint32_t n)
{
    union {
        uint32_t u;
        float f;
    } conv;

    conv.u = n;
    conv.f *= 4;
    return conv.u;
}

(This use of unions has unspecified, but not undefined, behavior in C1999 with technical corrigienda applied, and in C2011. In C1989 it was undefined, and in C++ it may still be undefined.)

(If you're asking this question because you need to do a little bit of floating-point math in a program that can't use the hardware floating point unit for some concrete reason, check your compiler's documentation - there may be an option you can set that makes it use its own software FP. But keep in mind that software floating point is orders of magnitude slower than the hardware.)

Post Status

Asked in February 2016
Viewed 2,819 times
Voted 9
Answered 1 times

Search




Leave an answer