0

I am currently doing a project involving the conversion of decimal numbers into IEEE 754 Floating Point representation. I am making use of a code provided by GeeksforGeeks for the conversion process and edited it to suit my project.

I am unsure as to how to modify the code so that it returns the appropriate Floating Point representation into the variables as the variables currently stores the decimal values instead.

I ran into the issue where the function being used to convert said decimal values is just simply printing the Floating Point representation. I would need to be able to return the printed Floating Point representation value into a variable. Is that possible? Else, is there an alternative method?

// C program to convert a real value
// to IEEE 754 floating point representaion

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;

int modifyBit(int n, int p, int b)
{
    int mask = 1 << p;
    return (n & ~mask) | ((b << p) & mask);
}


void printBinary(int n, int i)
{

    // Prints the binary representation
    // of a number n up to i-bits.
    int k;
    for (k = i - 1; k >= 0; k--) {

        if ((n >> k) & 1)
            printf("1");
        else
            printf("0");
    }
}

typedef union {

    float f;
    struct
    {

        // Order is important.
        // Here the members of the union data structure
        // use the same memory (32 bits).
        // The ordering is taken
        // from the LSB to the MSB.
        unsigned int mantissa : 23;
        unsigned int exponent : 8;
        unsigned int sign : 1;

    } raw;
} myfloat;

// Function to convert real value
// to IEEE foating point representation
void printIEEE(myfloat var)
{

    // Prints the IEEE 754 representation
    // of a float value (32 bits)

    printf("%d | ", var.raw.sign);
    printBinary(var.raw.exponent, 8);
    printf(" | ");
    printBinary(var.raw.mantissa, 23);
    printf("\n");
}

// Driver Code
int main()
{

    // Instantiate the union
    myfloat var, var2;
    int sub, sub2, mant, pos, finalMant;


    // Get the real value
    var.f = 1.25;
    var2.f = 23.5;


    // Get the IEEE floating point representation
    printf("IEEE 754 representation of %f is : \n",
           var.f);
    printIEEE(var);
    printf("No 2: %f : \n", var2.f);
    printIEEE(var2);
    printf("\n");

    //Get the exponent value for the respective variable
    //Need to compare which exponent is bigger
    printBinary(var2.raw.exponent, 8);
    printf("\n");
    printf("Exponent of Var in Decimal: %d: \n", var.raw.exponent);
    printf("Exponent of Var2 in Decimal: %d: \n", var2.raw.exponent);

    if (var.raw.exponent > var2.raw.exponent)
    {
        printf("1st is bigger than 2 \n");

        //Difference in exponent
        sub = var.raw.exponent - var2.raw.exponent;
        printf("Difference in exponent: %d \n", sub);

        //New mantissa with the new right shift
        mant = var2.raw.mantissa>>sub;

        //Modifying the hidden bit to be included into the mantissa
        pos = 23 - sub;
        finalMant = modifyBit(mant, pos, 1);

        //Print the final mantissa
        printf("New Binary : \n");
        printBinary(finalMant, 23);
    }
    else
    {
        printf("2nd bigger than 1 \n");

        //Difference in exponent
        sub = var2.raw.exponent - var.raw.exponent;
        printf("Difference in exponent: %d \n", sub);

        //New mantissa with the new right shift
        mant = var.raw.mantissa>>sub;

        //Modifying the hidden bit to be included into the mantissa
        pos = 23 - sub;
        finalMant = modifyBit(mant, pos, 1);

        //Print the final mantissa
        printf("New Binary : \n");
        printBinary(finalMant, 23);
    }
    return 0;
}

This code correctly converts the decimal value into the intended Floating Point representation. However, if I were to print the variable as it is using printf(finalMant) instead of printBinary, it would display as a decimal value instead of a Floating Point representation. This might be due to the lack of any return values.

melpomene
  • 84,125
  • 8
  • 85
  • 148
Kai
  • 31
  • 4
  • 1
    I think part of what you're looking for is [`sprintf`](https://linux.die.net/man/3/sprintf) – Federico klez Culloca Jul 30 '19 at 08:17
  • 2
    AFAIK using union in this way is forbidden in C++ and only allowed in C. It's not clear what do you need to return as the only point of this code is to print binary representation of float number and values of it's elements. Do you need binary representation as a string? – sklott Jul 30 '19 at 08:18
  • @sklott i am trying to return the floating point values into the `sign`, `exponent`, and `mantissa` variables as they currently contain decimal values instead. – Kai Jul 30 '19 at 08:21
  • 1
    https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h/31816096 – melpomene Jul 30 '19 at 08:23
  • 2
    You should never `#include `. It is not proper C++. It ruins portability and fosters terrible habits. See [Why should I not `#include `](https://stackoverflow.com/q/31816095). – L. F. Jul 30 '19 at 08:28
  • 2
    Also, please avoid `using namespace std;`. It is considered bad practice. See [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/q/1452721) – L. F. Jul 30 '19 at 08:28

1 Answers1

0

Based on clarification in comments you don't need to "return" anything. Just declare variable of type myfloat, put float in f member, and you can get sign, exponent and mantissa elements. I.e. something like this:

    myfloat cnv;
    cnv.f = someFloatVal;
    unsigned int mantissa = cnv.mantissa;

Just remember, that this is valid only for C, not for C++. (Although most of compilers support this, probably to be compatible with C, it is not guaranteed, and discouraged, by standard).

sklott
  • 2,634
  • 6
  • 17
  • Interesting discussion about [legality of type punning via unions](https://stackoverflow.com/questions/11373203/accessing-inactive-union-member-and-undefined-behavior)... – Aconcagua Jul 30 '19 at 08:53