CIN and Floating point numbers

Jan 30, 2013 at 3:15am
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.
Jan 30, 2013 at 3:24am
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;
}
Jan 30, 2013 at 5:31am
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?
Jan 30, 2013 at 5:35am
Answered my own question. That will truncate it after the decimal.
Jan 30, 2013 at 5:46am
Maybe convert the number to a string and deal with before and after the decimal separately then combine back together at the end.
Jan 30, 2013 at 6:35am
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?
Jan 30, 2013 at 7:22am
> 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() ) ;
}

Jan 30, 2013 at 4:46pm
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.
Jan 30, 2013 at 4:49pm
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.
Jan 30, 2013 at 5:25pm
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?
Jan 30, 2013 at 5:51pm
> 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.
Jan 31, 2013 at 2:49am
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 Jan 31, 2013 at 2:49am
Jan 31, 2013 at 2:34pm
>
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.