views:

2671

answers:

10

I want to take a floating point number in C++, like 2.25125, and a int array filled with the binary value that is used to store the float in memory (IEEE 754).

So I could take a number, and end up with a int num[16] array with the binary value of the float: num[0] would be 1 num[1] would be 1 num[2] would be 0 num[3] would be 1 and so on...

Putting an int into an array isn't difficult, just the process of getting the binary value of a float is where I'm stuck. Can you just read the binary in the memory that the float variable? If not, how could I go about doing this in C++?

EDIT: The reason for doing the comparison this way is that I am wanting to learn to do bitwise operations in C++.

+3  A: 
int fl = *(int*)&floatVar; //assuming sizeof(int) = sizeof(float)

int binaryRepresentation[sizeof(float) * 8];

for (int i = 0; i < sizeof(float) * 8; ++i)
    binaryRepresentation[i] = ((1 << i) & fl) != 0 ? 1 : 0;

Explanation

(1 << i) shifts the value 1, i bits to the left. The & operator computes the bitwise and of the operands.

The for loop runs once for each of the 32 bits in the float. Each time, i will be the number of the bit we want to extract the value from. We compute the bitwise and of the number and 1 << i:

Assume the number is: 1001011, and i = 2

1<<i will be equal to 0000100

  10001011
& 00000100
==========
  00000000

if i = 3 then:

  10001011
& 00001000
==========
  00001000

Basically, the result will be a number with ith bit set to the ith bit of the original number and all other bits are zero. The result will be either zero, which means the ith bit in the original number was zero or nonzero, which means the actual number had the ith bit equal to 1.

Mehrdad Afshari
That's not what he wants: The binary representation must be an array of size `sizeof(float) * CHAR_BIT` (-1)
Christoph
@Christoph: I doubt so. Look at the question. He says he wants a binary representation of the float in an int array.
Mehrdad Afshari
continued: To quote from the question: "So I could take a number, and end up with a int num[16] array with the binary value of the float: num[0] would be 1 num[1] would be 1 num[2] would be 0 num[3] would be 1 and so on..."
Mehrdad Afshari
He wants the int array to contain the bit pattern, ie one int for each bit - therefore, its size must be the number of bits in a float variable, ie 32 (he incorrectly assumed that a float value takes 16 bits...)
Christoph
Oops, my fault. Thanks for the point.
Mehrdad Afshari
looks good; removed downvote...
Christoph
Yes, what I am doing is seeing if two floats are the same without using comparison operators. So I will XOR each pair of bits (a bit from each float) and put the result in a bool variable. After comparing all the bits, if my bool value is still false, then the two numbers are the same.
Also, I now see I need 32 bits, not 16.
Do not assume there are 8 bits in a byte. Use CHAR_BIT.
Martin York
@unknown (yahoo): That's silly. It does not buy you anything. Assuming this homework: Put each float in an int do an xor on the ints.
Martin York
I think the number of programmers left in the world who deal with CHAR_BIT as a necessity could be counted on one hand... (as of 2007 I am no longer part of that crowd)
sixlettervariables
sixlettervariables. that's just silly... it's part of the language spec and it's the amount of bits in char. how about omitting the use of sizeof next...
Johannes Schaub - litb
I was pointing out the unhelpfulness of the CHAR_BIT side conversation to his original homework^W question...
sixlettervariables
This isn't homework, one of my professors asked me if I could do it for fun. It would be very simple to just subtract one float from another, and if you do not have 0, then they are not the same. But I think this is simply an exercise in working with bits and binary logic.
What's the kind of fun that professors ask for? It gives out some increase in GPA?
Mehrdad Afshari
Can you explain what is happening here:((1 << i)
Mehrdad, any reason for using the pretty much deprecated C-style cast instead of the recommended `reinterpret_cast` here? There's pretty much consensus that C-style cast should never be used – especially not in a “textbook” example.
Konrad Rudolph
@Konrad, It's shorter :) The sole purpose of my answer was the line in the for loop. I didn't want to clutter up the answer with unnecessary best practices.
Mehrdad Afshari
Thank you Mehrdad Afshari! You have been a great help.
A: 

Cast the int pointer to a float pointer, and you're done.

(Though I wouldn't declare it as an int array. I'd use void* to make it clear the the memory is being used as a dumping ground for other values.)

Incidentally, why don't you just use an array of floats?

benjismith
+1  A: 

If you need a particular floating point representation, you'll have to build that up semantically from the float itself, not by bit-copying.

c0x standard: http://c0x.coding-guidelines.com/5.2.4.2.2.html doesn't define the format of floating point numbers.

Douglas Leeder
+1  A: 

Can you just read the binary in the memory that the float variable?

Yes. Static cast a pointer to it to an int pointer and read the bits from the result. An IEEE 754 float is 32 bits.

codekaizen
+1  A: 

Create a union of float and and unsigned long. set the value of the float member and iterate over the bits of the unsigned long value as already described in other answers.

This will eliminate the cast operators.

Noel Walters
+1  A: 

You can use an unsigned char to read the float byte by byte into the integer array:

unsigned int bits[sizeof (float) * CHAR_BIT];
unsigned char const *c = static_cast<unsigned char const*>(
    static_cast<void const*>(&my_float)
);

for(size_t i = 0; i < sizeof(float) * CHAR_BIT; i++) {
    int bitnr = i % CHAR_BIT;
    bits[i] = (*c >> bitnr) & 1;
    if(bitnr == CHAR_BIT-1)
        c++;
}

// the bits are now stored in "bits". one bit in one integer.

By the way, if you just want to compare the bits (as you comment on another answer) use memcmp:

memcmp(&float1, &float2, sizeof (float));
Johannes Schaub - litb
+4  A: 

Use union and bitset:

#include <iostream>
#include <bitset>

int main()
{
    union
    {
         float input;   // assumes sizeof(float) == sizeof(int)
         int   output;
    }    data;

    data.input = 2.25125;

    std::bitset<sizeof(float) * CHAR_BIT>   bits(data.output);


    std::cout << bits << std::endl;

    // or

    std::cout << "BIT 4: " << bits[4] << std::endl;
    std::cout << "BIT 7: " << bits[7] << std::endl;
}

It may not be an array but you can access bits with [] operator as if you were using an array.

Output

$ ./bits
01000000000100000001010001111011
BIT 4: 1
BIT 7: 0
Martin York
This looks really promising. After I get home I will test it out. Thanks!
Yep! This is _exactly_ what I was looking for. Thank you Seattle!
ieee754 floats are always 32 bits, c++ is spec'ed to use ieee754 for it floating point types.Long is also spec'ed to be 32 bits.Change the union to use long instead of int, and you'll have truly portable code.
caspin
A: 

Looking at the comments in this answer (http://stackoverflow.com/questions/474007/floating-point-to-binary-valuec#474014) the reason to do this is to perform a bitwise comparison of two values.

#include <iostream>

int main()
{
    union Flip
    {
         float input;   // assumes sizeof(float) == sizeof(int)
         int   output;
    };

    Flip    data1;
    Flip    data2;
    Flip    data3;

    data1.input = 2.25125;
    data2.input = 2.25126;
    data3.input = 2.25125;

    bool    test12  = data1.output ^ data2.output;
    bool    test13  = data1.output ^ data3.output;
    bool    test23  = data2.output ^ data3.output;

    std::cout << "T1(" << test12 << ") T2(" << test13 << ") T3(" << test23 << ")\n";


}
Martin York
A: 

Easiest way:

float myfloat;
file.read((char*)(&myfloat),sizeof(float));
Alexander Rafferty
A: 

code float 2 binary in c++. example: input float=5.25 output binary= 0000000000000101 0000000000000001

nima