Issue adapting C code to C++

Hello,

I adapted some C code to convert a floating point to IEEE 754 binary

The code works in Xcode and does (in many cases) convert correctly.

Problem is, I am compiling in g++ as well and get the error

"segmentation fault (core dumped)"

I think this has to do with incorrectly specifying the address. Though I could be wrong, I am only a beginner.

Let me know if any other information is necessary.

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
39
40
#include <iomanip>
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <cstdlib>

using namespace std;

void print_binary(float f)
{
    signed long *floaty = (signed long *)&f;
    int i;
    
    for(i = 0; i <= 31; i++)
    {
        if ((*floaty) >> (31-i) & 1)
            cout << "1";
        else
            cout << "0";
    }
}

void float_pieces(float f,
                 signed char *sign,
                 signed short *exponent,
                 signed long *significand)
{
    signed long *floaty = (signed long *)&f;
    
    *sign = (signed char) (*floaty >> 31);
    *exponent = (signed short) (*floaty >> 23 & 0x7FF);
    *significand = *floaty & 0x000FFFFFFFFFFFFF;
}

int main(int argc, char *argv[])
{
    float f = atof(argv[1]);
    
    print_binary(f);
}
I think it is more likely an issue with line 37, since the specification for atof() indicates that the argument must be valid, otherwise you'll get undefined behavior -- which in your case is a segmentation fault.

Your code has one other significant issue: you are doing stuff with signed values. Don't do that. Use unsigned values. Again, bit manipulations are not guaranteed to be defined on signed values.

Since you are using C++, you can make your life easier by using STL algorithms. That, and I'm not sure where you are getting some of the literal values you are using to dissect a 4-byte float.

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
#include <bitset>
#include <cstdint>
#include <iostream>
using namespace std;

union float_int
{
  float    f;
  uint32_t n;
};

void print_binary( float f )
{
  float_int d;
  d.f = f;
  cout << bitset <32> ( d.n ) << "\n";
}

void float_pieces(
  float f,
  bool& sign, 
  unsigned char& exponent,
  unsigned short& mantissa )
{
  float_int d;
  d.f = f;
  sign     =  d.n        & 0x8000;
  exponent = (d.n >> 23) & 0xFF;
  mantissa =  d.n        & 0x7FFFFF;
}

int main( int argc, char** argv )
{
  float f = (argc > 1) ? atof( argv[1] ) : 0.f;

  print_binary( f );
}

Hope this helps.
Last edited on
Thanks Duoas, changing to unsigned worked well, which makes a lot of sense now that I think about it.
Topic archived. No new replies allowed.