CIN and Floating point numbers

So I'm writing a program that is supposed to output the binary representations of numbers using a bitwise operator and a mask. The extra credit portion(Which we were told we had to do.) Asks us to change from the integer operations we were doing and switch to floating point. The issue I am running into is getting the insertion operator to continue after it encounters a non integer (a period). It immediately takes the integer preceding the . and runs the operations (Then terminates because my loop gets a input to see if it should continue and a period is not 'Y') Basically how do I cin a number like 3.14159.
I have tried getLine (cin, varName); that produces the same issue. The variable is set to a float. Here is what my code looks like at the moment.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>


using namespace std;

void printBinary(float);

int main()
{
    float num1;
    char yesNo;
    do
    {
    cout << "Please enter an integer: " << endl;
    getline (cin, num1);
    printBinary(num1);
    cout << "Would you like to enter another integer? (Y/N) :" << endl;
    cin >> yesNo;
    toupper(yesNo);
    }while (yesNo == 'Y');
    return 0;
}



void printBinary(float num1) {
    unsigned float mask = 0x80000000;

    for (int count = 1 ; count <= 32; count++)
    {
        if (num1 & mask)
            cout << "1";
        else
            cout << "0";
        mask >>= 1;
    }
    cout << endl;
}
I'm an idiot and this was not in my project in code::blocks. Though now it doesn't work due to bitwise operators not being able to compare floats. Would a static_cast<int> work?
Answered my own question. That will truncate it after the decimal.
Maybe convert the number to a string and deal with before and after the decimal separately then combine back together at the end.
The point of the exercise is to find out how my system stores floating point decimals in binary form. While I know that it is IEEE standard to store it as 1 bit sign, 10 bits exponent, and 22 bits mantissa, I have to show it. The if (num1 & mask) does the work in this case, but unfortunately it does not work when using floats and integers. Another person on another board mention that you had to do a union when comparing floats and integers in bitwise operations, but I haven't been able to grasp that concept just yet. Anyone have any pointers?
> The point of the exercise is to find out how my system stores floating point decimals in binary form

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <limits>
#include <bitset>
#include <iostream>

void print_bits( float n )
{
    std::cout << std::showpos << std::showpoint << n << " => " ;
    const unsigned char* p = reinterpret_cast<const unsigned char*>( &n ) ;
    for( std::size_t i = 0 ; i < sizeof(n) ; ++i )
        std::cout << std::bitset< std::numeric_limits<unsigned char>::digits >( p[i] ) ;
    std::cout << '\n' ;
}

int main()
{
    typedef std::numeric_limits<float> limits ;

    std::cout << std::boolalpha << "ieee 754? " << limits::is_iec559 << '\n'
               << "base-radix of the representation: " << limits::radix << '\n'
               << "number of (base-radix) digits in the mantissa: " << limits::digits << '\n'
               << "minimum value of exponent (base-radix): " << limits::min_exponent << '\n'
               << "upper bound of exponent (base-radix): " << limits::max_exponent << '\n'
               << "can represent infinity? " << limits::has_infinity << '\n'
               << "quiet nan? " << limits::has_quiet_NaN << '\n'
               << "signaling nan? " << limits::has_signaling_NaN << '\n'
               << "support subnormal values? " << ( limits::has_denorm == std::denorm_present ) << '\n'
               << "rounding style: " << limits::round_style << '\n' ;
               // etc.

    print_bits( +1.0f ) ;
    print_bits( -1.0f ) ;
    print_bits( +1.234e+6f ) ;
    print_bits( -1.234e-6f ) ;
    print_bits( -1.234e-6f ) ;
    print_bits( limits::infinity() ) ;
    print_bits( limits::quiet_NaN() ) ;
    print_bits( limits::signaling_NaN() ) ;
}

Thanks, while that is I'm sure technically going to show me the answers, after talking to the professor I need to trick the compiler into thinking that it is using a integer by using a pointer. I just as clueless now I was before but, atleast I have a starting point.
Which after rereading your code it seems you may be doing. I am just not used to the std:: stuff as we are supposed to use the namespace std.
So if I am reading this correctly the print_bits function goes by printing the the input (Floating number in this case) then declares a constant char pointer called p and assigns it the address of n using a reinterpret_cast to get the address of a fundamentally different class (float) to be a address contained in pointer of the const char type. then for i = 0 to 1 less then the size of n you do an operation that I don't understand. Could you break down what is happening in line 10 for me?
> then for i = 0 to 1 less then the size of n you do an operation that I don't understand.

We are inspecting the float object as a sequence of bytes.
And for each byte in the sequence of bytes, we print the out the bits as 0 or 1.

For convenience, we ask a std::bitset<N> (where N is the number of bits in a byte) to do the printing for us.
http://en.cppreference.com/w/cpp/utility/bitset

Not that the bytes are printed from lower address to higher address; while interpreting them, you may want to take endianness into account.
Apparently all I had to do to get my code to work the way I wanted to was just
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void printBinary(float num1) {
   int *floatMem = (int*) &num1
    unsigned float mask = 0x80000000;

    for (int count = 1 ; count <= 32; count++)
    {
        if (*floatMem & mask)
            cout << "1";
        else
            cout << "0";
        mask >>= 1;
    }
    cout << endl;
}

Last edited on
>
1
2
void printBinary(float num1) {
 int *floatMem = (int*) &num1 ;


Using *floatMem in any way violates the strict strict aliasing rules of C++, and leads to undefined behaviour.

Topic archived. No new replies allowed.