Reputation: 13
Yet my lectures in C++ at university began yet i got my first problems. Our task was it to implement a self made structure in C++ for floating points via the IEEE 754 standard:
Create a data structure that allows you to store a float, read its raw byte representation and its internal representation as s, e and m. Use a combination of union and bit-field-struct. Write a program where a float number is assigned to the float part of the structure and the raw and s/e/m representation is printed. Use hexadecimal output for raw and m.
What i had so far is the following:
#include <stdio.h>
#include <math.h>
union {
struct KFloat {
//Using bit fields for our self made float. s sign, e exponent, m mantissa
//It should be unsigned because we simply use 0 and 1
unsigned int s : 1, e : 8, m : 23;
};
//One bit will be wasted for our '.'
char internal[33];
};
float calculateRealFloat(KFloat kfloat) {
if(kfloat.s == 0) {
return (1.0+kfloat.m)*pow(2.0, (kfloat.e-127.0));
} else if (kfloat.s == 1) {
return (-1.0)*((1.0+kfloat.m)*pow(2.0, (kfloat.e-127.0)));
}
//Error case when s is bigger 1
return 0.0;
}
int main(void) {
KFloat kf_pos = {0, 128, 1.5707963705062866};//This should be Pi (rounded) aka 3.1415927
KFloat kf_neg = {1, 128, 1.5707963705062866};//Pi negative
float f_pos = calculateRealFloat(kf_pos);
float f_neg = calculateRealFloat(kf_neg);
printf("The positive float is %f or ",f_pos);
printf("%e\n", f_pos);
printf("The negative float is %f or ",f_neg);
printf("%e", f_neg);
return 0;
}
The first error with this code is clearly that the mantissa is absolutely wrong but i have no idea how to fix this.
Upvotes: 0
Views: 4012
Reputation: 1310
Bruce Dawson has an excellent series of blog posts on floating point representation and arithmetic. The latest in the series, which has a bunch of links to previous posts that discusses this subject matter in detail, is here.
Upvotes: 1
Reputation: 6915
please reread the task:
Create a data structure that allows you to store a float, read its raw byte representation and its internal representation as s, e and m.
this does not mean that you should store a string
I would do this the following way:
union MyFloat
{
unsigned char rawByteDataRep[4];
unsigned int rawDataRep;
float floatRep;
struct{ // not checked this part just copied from you
unsigned s : 1;
unsigned e : 8;
unsigned m : 23;
} componentesRep;
}
but be careful! Besides the fact that this union-conversion pattern is widely used, the C-Standard states that the result is undefined behaviour if you read another unionmember than the one that was written.
Edit: added uint32 rep
void testMyfloat()
{
MyFloat mf;
mf.floatRep = 3.14;
printf("The float %f is assembled from sign %i magnitude 0x%08x and exponent %i and looks in memory like that 0x%08x.\n",
mf.floatRep,
(int)mf.componentesRep.s,
(unsigned int)mf.componentesRep.m,
(int)mf.componentesRep.e,
mf.componentesRep.rawDataRep);
}
Upvotes: 2