Code to print each part of double as a separate group of bits

V

Virtual_X

As in IEEE754

double consist of
sign bit
11 bits for exponent
52 bits for fraction

i write this code to print double parts as it explained in ieee754
i want to know if the code contain any bug , i am still c++ beginner

#include <iostream>

using namespace std;


struct byte
{
bool bit[8]; // 8 = sizeof(double);
};

void pb(unsigned char *ch,byte *bin)
{
for(int i=0;i <=7;i++)
for(int o=7;o >=0;o--)
{
if(ch & 1<<o)
bin.bit[abs(o-7)]= true;
else
bin.bit[abs(o-7)]= false;
}
}

int main()
{
double x=215.2564878765465;
byte v[8];

pb(reinterpret_cast<unsigned char*>(&x),v);

//Printing the signbit
cout << "The sign bit\n" << v[0].bit[0] << endl;
cout <<
"\n---------------------------------------------------------\n";
/*--------------------------------------------------*/
//Printing the expoent bits = 11 bit
cout << "The exponent bits= 11 bits\n\n";
for(int i=1;i<8;i++)
cout << v[0].bit;
//still 4 bits
for(int i=0;i<4;i++)
cout << v[1].bit;

cout <<
"\n---------------------------------------------------------\n";
/*--------------------------------------------------*/
//Printing the fraction bits = 52 bit
//print the remain 4 bits
cout << "Fraction bits = 52 bit\n\n";
for(int i=4;i<8;i++)
cout << v[1].bit;

//print all the remain bits
for(int i=2;i<8;i++)
for(int o=0;o<8;o++)
{
cout << v.bit[o];
}
return 0;
}
 
V

Victor Bazarov

Virtual_X said:
As in IEEE754

double consist of
sign bit
11 bits for exponent
52 bits for fraction

i write this code to print double parts as it explained in ieee754
i want to know if the code contain any bug , i am still c++ beginner

#include <iostream>

using namespace std;


struct byte
{
bool bit[8]; // 8 = sizeof(double);

What a misleading comment! struct is called 'byte' What does the
size of the array (8) have to do with the size of 'double'? It is
a pure coincidence, isn't it?
};

void pb(unsigned char *ch,byte *bin)
{
for(int i=0;i <=7;i++)
for(int o=7;o >=0;o--)
{
if(ch & 1<<o)
bin.bit[abs(o-7)]= true;
else
bin.bit[abs(o-7)]= false;


It is much better to just write

bin.bit[abs(o-7)] = (ch & (1 << o));

and 'abs(o-7)' could be simply rewritten as '7-o', no?
}
}

int main()
{
double x=215.2564878765465;
byte v[8];

pb(reinterpret_cast<unsigned char*>(&x),v);

//Printing the signbit
cout << "The sign bit\n" << v[0].bit[0] << endl;
cout <<
"\n---------------------------------------------------------\n";
/*--------------------------------------------------*/
//Printing the expoent bits = 11 bit
cout << "The exponent bits= 11 bits\n\n";
for(int i=1;i<8;i++)
cout << v[0].bit;
//still 4 bits
for(int i=0;i<4;i++)
cout << v[1].bit;

cout <<
"\n---------------------------------------------------------\n";
/*--------------------------------------------------*/
//Printing the fraction bits = 52 bit
//print the remain 4 bits
cout << "Fraction bits = 52 bit\n\n";
for(int i=4;i<8;i++)
cout << v[1].bit;

//print all the remain bits
for(int i=2;i<8;i++)
for(int o=0;o<8;o++)
{
cout << v.bit[o];
}
return 0;
}


Does your program work as expected? It seems to have the source
data hard-coded; what happens if you allow entering the value (in
the standard input or as the command-line argument)? You could
test it with a much wider range of values...

V
 
V

Virtual_X

Virtual_X said:
As in IEEE754
double consist of
sign bit
11 bits for exponent
52 bits for fraction
i write this code to print double parts as it explained in ieee754
i want to know if the code contain any bug , i am still c++ beginner
#include <iostream>
using namespace std;
struct byte
{
bool bit[8]; // 8 = sizeof(double);

What a misleading comment! struct is called 'byte' What does the
size of the array (8) have to do with the size of 'double'? It is
a pure coincidence, isn't it?
void pb(unsigned char *ch,byte *bin)
{
for(int i=0;i <=7;i++)
for(int o=7;o >=0;o--)
{
if(ch & 1<<o)
bin.bit[abs(o-7)]= true;
else
bin.bit[abs(o-7)]= false;


It is much better to just write

bin.bit[abs(o-7)] = (ch & (1 << o));

and 'abs(o-7)' could be simply rewritten as '7-o', no?


int main()
{
double x=215.2564878765465;
byte v[8];
pb(reinterpret_cast<unsigned char*>(&x),v);
//Printing the signbit
cout << "The sign bit\n" << v[0].bit[0] << endl;
cout <<
"\n---------------------------------------------------------\n";
/*--------------------------------------------------*/
//Printing the expoent bits = 11 bit
cout << "The exponent bits= 11 bits\n\n";
for(int i=1;i<8;i++)
cout << v[0].bit;
//still 4 bits
for(int i=0;i<4;i++)
cout << v[1].bit;

cout <<
"\n---------------------------------------------------------\n";
/*--------------------------------------------------*/
//Printing the fraction bits = 52 bit
//print the remain 4 bits
cout << "Fraction bits = 52 bit\n\n";
for(int i=4;i<8;i++)
cout << v[1].bit;

//print all the remain bits
for(int i=2;i<8;i++)
for(int o=0;o<8;o++)
{
cout << v.bit[o];
}
return 0;
}


Does your program work as expected? It seems to have the source
data hard-coded; what happens if you allow entering the value (in
the standard input or as the command-line argument)? You could
test it with a much wider range of values...


the program works well and i only want to divide double to separate
bits "not to make it a general program which allow the user to input
and output"

thanks alot
 
L

Laurent D.A.M. MENTEN

My personal taste goes to some code like this one:

#include <iostream>

using namespace std;

struct double_bits
{
unsigned long fraction : 52;
unsigned long exponent : 11;
unsigned long sign : 1;
};

union double_union
{
double value;
struct double_bits bits;
};

int main()
{
double_union x = {215.2564878765465};

cout << "value : " << x.value << endl;
cout << "sign : " << x.bits.sign << endl;
cout << "exponent : " << x.bits.exponent << endl;
cout << "fraction : " << x.bits.fraction << endl;

return 0;
}

:wq
 
V

Virtual_X

Virtual_X said:
As in IEEE754
double consist of
sign bit
11 bits for exponent
52 bits for fraction
i write this code to print double parts as it explained in ieee754
i want to know if the code contain any bug , i am still c++ beginner
#include <iostream>
using namespace std;
struct byte
{
bool bit[8]; // 8 = sizeof(double);

What a misleading comment! struct is called 'byte' What does the
size of the array (8) have to do with the size of 'double'? It is
a pure coincidence, isn't it?

sorry i don't know what you exactly mean
but i think the remain code will explain why i make array(8)
"because byte = 8 bits"
void pb(unsigned char *ch,byte *bin)
{
for(int i=0;i <=7;i++)
for(int o=7;o >=0;o--)
{
if(ch & 1<<o)
bin.bit[abs(o-7)]= true;
else
bin.bit[abs(o-7)]= false;


It is much better to just write

bin.bit[abs(o-7)] = (ch & (1 << o));

and 'abs(o-7)' could be simply rewritten as '7-o', no?


int main()
{
double x=215.2564878765465;
byte v[8];
pb(reinterpret_cast<unsigned char*>(&x),v);
//Printing the signbit
cout << "The sign bit\n" << v[0].bit[0] << endl;
cout <<
"\n---------------------------------------------------------\n";
/*--------------------------------------------------*/
//Printing the expoent bits = 11 bit
cout << "The exponent bits= 11 bits\n\n";
for(int i=1;i<8;i++)
cout << v[0].bit;
//still 4 bits
for(int i=0;i<4;i++)
cout << v[1].bit;

cout <<
"\n---------------------------------------------------------\n";
/*--------------------------------------------------*/
//Printing the fraction bits = 52 bit
//print the remain 4 bits
cout << "Fraction bits = 52 bit\n\n";
for(int i=4;i<8;i++)
cout << v[1].bit;

//print all the remain bits
for(int i=2;i<8;i++)
for(int o=0;o<8;o++)
{
cout << v.bit[o];
}
return 0;
}


Does your program work as expected? It seems to have the source
data hard-coded; what happens if you allow entering the value (in
the standard input or as the command-line argument)? You could
test it with a much wider range of values...

V
 
V

Victor Bazarov

Laurent said:
My personal taste goes to some code like this one:

#include <iostream>

using namespace std;

struct double_bits
{
unsigned long fraction : 52;
unsigned long exponent : 11;
unsigned long sign : 1;
};

union double_union
{
double value;
struct double_bits bits;
};

int main()
{
double_union x = {215.2564878765465};

cout << "value : " << x.value << endl;
cout << "sign : " << x.bits.sign << endl;
cout << "exponent : " << x.bits.exponent << endl;
cout << "fraction : " << x.bits.fraction << endl;

return 0;
}

Unfortunately, unless something has changed, this is not the
legal use of 'union'. You are allowed to only access the member
that you set. If you initialise it with 'double', you can only
extract the 'double' from there.

My preferred way would be to convert a double into an array of
char, and then build a bitset from that.

V
 
L

Laurent D.A.M. MENTEN

Ooops I forgot my box is 64bit, for code that compile and run correctly
on a 32bit system, the following structure is more suitable. Note that I
use gcc and there may be compiler specific types for 64 bits integer,
long long may not work on these...

struct double_bits
{
unsigned long long fraction : 52;
unsigned long long exponent : 11;
unsigned long long sign : 1;
};


Laurent D.A.M. MENTEN a écrit :
 
V

Victor Bazarov

Virtual_X said:
Virtual_X said:
As in IEEE754
double consist of
sign bit
11 bits for exponent
52 bits for fraction
i write this code to print double parts as it explained in ieee754
i want to know if the code contain any bug , i am still c++ beginner
#include <iostream>
using namespace std;
struct byte
{
bool bit[8]; // 8 = sizeof(double);

What a misleading comment! struct is called 'byte' What does the
size of the array (8) have to do with the size of 'double'? It is
a pure coincidence, isn't it?

sorry i don't know what you exactly mean
but i think the remain code will explain why i make array(8)
"because byte = 8 bits"

Whenever you write your code, remember that it's going to be read by
somebody at some point. If not, if you write your code once and never
let anybody (even yourself) look at it again, then why put any comments
in it at all?

The declaration of the 'bit' member is

bool bit[8];

The comment right next to it is

// 8 = sizeof(double)

Does that mean that the '8' in the declaration is used because on your
system 'sizeof(double)' yields 8? That's how I am reading it.

BTW, not all systems that support IEEE 754 double have their 'byte'
equal to 8 bits. So, your program is only portable to the systems
that share the size of 'char' with yours.

V
 
L

Laurent D.A.M. MENTEN

Victor Bazarov a écrit :
Unfortunately, unless something has changed, this is not the
legal use of 'union'. You are allowed to only access the member
that you set. If you initialise it with 'double', you can only
extract the 'double' from there.

My preferred way would be to convert a double into an array of
char, and then build a bitset from that.

V

Yet it might not be the legal use of 'union', it is the most common use
I have seen for it...
 
L

Laurent D.A.M. MENTEN

Virtual_X a écrit :
nice idea but you still want to convert the result to 0 and 1

a function that prints an integer as a binary string is rather trivial!
 
V

Virtual_X

Virtual_X said:
Virtual_X wrote:
As in IEEE754
double consist of
sign bit
11 bits for exponent
52 bits for fraction
i write this code to print double parts as it explained in ieee754
i want to know if the code contain any bug , i am still c++ beginner
#include <iostream>
using namespace std;
struct byte
{
bool bit[8]; // 8 = sizeof(double);
What a misleading comment! struct is called 'byte' What does the
size of the array (8) have to do with the size of 'double'? It is
a pure coincidence, isn't it?
sorry i don't know what you exactly mean
but i think the remain code will explain why i make array(8)
"because byte = 8 bits"

Whenever you write your code, remember that it's going to be read by
somebody at some point. If not, if you write your code once and never
let anybody (even yourself) look at it again, then why put any comments
in it at all?

The declaration of the 'bit' member is

bool bit[8];

The comment right next to it is

// 8 = sizeof(double)

Does that mean that the '8' in the declaration is used because on your
system 'sizeof(double)' yields 8? That's how I am reading it.
that was a mistake
i change the code and forget to remove the comment , sorry :)
BTW, not all systems that support IEEE 754 double have their 'byte'
equal to 8 bits. So, your program is only portable to the systems
that share the size of 'char' with yours.
i think the code can be portable if we use sizeof sothat we can know
the size of double
and for unsigned char may be we can change it by bool "i didn't try
that" which always 1 byte
 
C

Christopher

Virtual_X said:
Virtual_X wrote:
As in IEEE754
double consist of
sign bit
11 bits for exponent
52 bits for fraction
i write this code to print double parts as it explained in ieee754
i want to know if the code contain any bug , i am still c++ beginner
#include <iostream>
using namespace std;
struct byte
{
bool bit[8]; // 8 = sizeof(double);
What a misleading comment! struct is called 'byte' What does the
size of the array (8) have to do with the size of 'double'? It is
a pure coincidence, isn't it?
sorry i don't know what you exactly mean
but i think the remain code will explain why i make array(8)
"because byte = 8 bits"
Whenever you write your code, remember that it's going to be read by
somebody at some point. If not, if you write your code once and never
let anybody (even yourself) look at it again, then why put any comments
in it at all?
The declaration of the 'bit' member is
bool bit[8];
The comment right next to it is
// 8 = sizeof(double)
Does that mean that the '8' in the declaration is used because on your
system 'sizeof(double)' yields 8? That's how I am reading it.

that was a mistake
i change the code and forget to remove the comment , sorry :)
BTW, not all systems that support IEEE 754 double have their 'byte'
equal to 8 bits. So, your program is only portable to the systems
that share the size of 'char' with yours.

i think the code can be portable if we use sizeof sothat we can know
the size of double
and for unsigned char may be we can change it by bool "i didn't try
that" which always 1 byte





- Show quoted text -- Hide quoted text -

- Show quoted text -


My 2 cents of advice is to change the habit of using abbreviated or
short names such as "pb" "ch" "v" in your code. It is less readable
and harder to maintain for others, as well as yourself! You might know
what "pb" meant 4 hours from writing the code, but 6 months later,
you'll have to analyze the entire function to remember its meaning.
Use function and variable names that give the reader a sense of what
it represents. For example "ParseBits" is a better function name then
"pb"
 
V

Virtual_X

Virtual_X said:
Virtual_X wrote:
As in IEEE754
double consist of
sign bit
11 bits for exponent
52 bits for fraction
i write this code to print double parts as it explained in ieee754
i want to know if the code contain any bug , i am still c++ beginner
#include <iostream>
using namespace std;
struct byte
{
bool bit[8]; // 8 = sizeof(double);
What a misleading comment! struct is called 'byte' What does the
size of the array (8) have to do with the size of 'double'? It is
a pure coincidence, isn't it?
sorry i don't know what you exactly mean
but i think the remain code will explain why i make array(8)
"because byte = 8 bits"
Whenever you write your code, remember that it's going to be read by
somebody at some point. If not, if you write your code once and never
let anybody (even yourself) look at it again, then why put any comments
in it at all?
The declaration of the 'bit' member is
bool bit[8];
The comment right next to it is
// 8 = sizeof(double)
Does that mean that the '8' in the declaration is used because on your
system 'sizeof(double)' yields 8? That's how I am reading it.

that was a mistake
i change the code and forget to remove the comment , sorry :)
BTW, not all systems that support IEEE 754 double have their 'byte'
equal to 8 bits. So, your program is only portable to the systems
that share the size of 'char' with yours.

i think the code can be portable if we use sizeof sothat we can know
the size of double
and for unsigned char may be we can change it by bool "i didn't try
that" which always 1 byte



i have write another powerful function "as i thought :)" to check
double equality with very high
precision because it check equality for every bit instead of the
"Microsoft msdn method"

here's my function "depend on the pb()"

bool d_eq(double x,double y)
{
byte bx[8];
byte by[8];

pb(reinterpret_cast<unsigned char*>(&x),bx);
pb(reinterpret_cast<unsigned char*>(&y),by);

for(int i=0;i < 8;i++)
for(int o=0;o < 8;o++)
if (bx.bit[o] != by.bit[o]) return false;

return true;
}


and Microsoft msdn method

#define EPSILON 0.0001 // Define your own tolerance
#define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))

int main() {
float a, b, c;

a = 1.345f;
b = 1.123f;
c = a + b;
// if (FLOAT_EQ(c, 2.468)) // Remove comment for correct result
if (c == 2.468) // Comment this line for correct result
printf_s("They are equal.\n");
else
printf_s("They are not equal! The value of c is %13.10f "
"or %f",c,c);
}

you can find it here
http://msdn2.microsoft.com/en-us/library/c151dt3s(VS.80).aspx

i alway thought that C/C++ really powerful
 
K

Kai-Uwe Bux

Virtual_X said:
i have write another powerful function "as i thought :)" to check
double equality with very high
precision because it check equality for every bit instead of the
"Microsoft msdn method"

here's my function "depend on the pb()"

bool d_eq(double x,double y)
{
byte bx[8];
byte by[8];

pb(reinterpret_cast<unsigned char*>(&x),bx);
pb(reinterpret_cast<unsigned char*>(&y),by);

for(int i=0;i < 8;i++)
for(int o=0;o < 8;o++)
if (bx.bit[o] != by.bit[o]) return false;

return true;
}


Where [quoted from some other posting]:
struct byte
{
bool bit[8]; // 8 = sizeof(double);
};

void pb(unsigned char *ch,byte *bin)
{
for(int i=0;i <=7;i++)
for(int o=7;o >=0;o--)
{
if(ch & 1<<o)
bin.bit[abs(o-7)]= true;
else
bin.bit[abs(o-7)]= false;
}
}



May I ask what advantage d_eq(x,y) has compared to x==y?

Also, what do you gain compared to something like this

template < typename T >
bool equal_representation ( T const & lhs, T const & rhs ) {
unsigned char const * lhs_iter =
static_cast< unsigned char const * >
( static_cast< void const * >( &lhs ) );
unsigned char const * rhs_iter =
static_cast< unsigned char const * >
( static_cast< void const *>( &rhs ) );
return ( std::equal( lhs_iter, lhs_iter+sizeof(T), rhs_iter ) );
}

Here the question is: what do you gain from taking the bytes apart and
looking at each bit individually? Just comaring the bytes should be
sufficient.

and Microsoft msdn method

#define EPSILON 0.0001 // Define your own tolerance
#define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))

int main() {
float a, b, c;

a = 1.345f;
b = 1.123f;
c = a + b;
// if (FLOAT_EQ(c, 2.468)) // Remove comment for correct result
if (c == 2.468) // Comment this line for correct result
printf_s("They are equal.\n");
else
printf_s("They are not equal! The value of c is %13.10f "
"or %f",c,c);
}

Have you tried whether the d_eq() method will give you the desired results?
I would strongly doubt it.


Best

Kai-Uwe Bux
 
C

Christopher

Virtual_X wrote:
Virtual_X wrote:
As in IEEE754
double consist of
sign bit
11 bits for exponent
52 bits for fraction
i write this code to print double parts as it explained in ieee754
i want to know if the code contain any bug , i am still c++ beginner
#include <iostream>
using namespace std;
struct byte
{
bool bit[8]; // 8 = sizeof(double);
What a misleading comment! struct is called 'byte' What does the
size of the array (8) have to do with the size of 'double'? It is
a pure coincidence, isn't it?
sorry i don't know what you exactly mean
but i think the remain code will explain why i make array(8)
"because byte = 8 bits"
Whenever you write your code, remember that it's going to be read by
somebody at some point. If not, if you write your code once and never
let anybody (even yourself) look at it again, then why put any comments
in it at all?
The declaration of the 'bit' member is
bool bit[8];
The comment right next to it is
// 8 = sizeof(double)
Does that mean that the '8' in the declaration is used because on your
system 'sizeof(double)' yields 8? That's how I am reading it.
that was a mistake
i change the code and forget to remove the comment , sorry :)
i think the code can be portable if we use sizeof sothat we can know
the size of double
and for unsigned char may be we can change it by bool "i didn't try
that" which always 1 byte

i have write another powerful function "as i thought :)" to check
double equality with very high
precision because it check equality for every bit instead of the
"Microsoft msdn method"

here's my function "depend on the pb()"

bool d_eq(double x,double y)
{
byte bx[8];
byte by[8];

pb(reinterpret_cast<unsigned char*>(&x),bx);
pb(reinterpret_cast<unsigned char*>(&y),by);

for(int i=0;i < 8;i++)
for(int o=0;o < 8;o++)
if (bx.bit[o] != by.bit[o]) return false;

return true;

}

and Microsoft msdn method

#define EPSILON 0.0001 // Define your own tolerance
#define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))

int main() {
float a, b, c;

a = 1.345f;
b = 1.123f;
c = a + b;
// if (FLOAT_EQ(c, 2.468)) // Remove comment for correct result
if (c == 2.468) // Comment this line for correct result
printf_s("They are equal.\n");
else
printf_s("They are not equal! The value of c is %13.10f "
"or %f",c,c);

}

you can find it herehttp://msdn2.microsoft.com/en-us/library/c151dt3s(VS.80).aspx

i alway thought that C/C++ really powerful- Hide quoted text -

- Show quoted text -



Unless I am missing something, your method is attempting the
equivalent of the built in == operator, which should never ever be
used to check equality on floating point types. Because floating
points are always rounded to the best binary representation.

float x = 0.01f * 10.0f;
if( x == 0.1f )
{
// Will not always return true!!!
}

Hence the Microsoft method you found where some threshhold is used.
Most people seem to code thier own equality method that takes two
doubles and a threshold as parameters so you can check if the two
doubles are "close enough" to each other in the context they are used.
This isn't specific to MS or Linux environments, I've seen such
methods done in both. You wouldn't necessarilly want to measure feet a
car has traveled around the world to a presision of .00000001, but you
might for say the width of skin cell in centimeters.
 
V

Virtual_X

Virtual_X said:
i have write another powerful function "as i thought :)" to check
double equality with very high
precision because it check equality for every bit instead of the
"Microsoft msdn method"
here's my function "depend on the pb()"
bool d_eq(double x,double y)
{
byte bx[8];
byte by[8];
pb(reinterpret_cast<unsigned char*>(&x),bx);
pb(reinterpret_cast<unsigned char*>(&y),by);
for(int i=0;i < 8;i++)
for(int o=0;o < 8;o++)
if (bx.bit[o] != by.bit[o]) return false;

return true;
}

Where [quoted from some other posting]:


struct byte
{
bool bit[8]; // 8 = sizeof(double);
};
void pb(unsigned char *ch,byte *bin)
{
for(int i=0;i <=7;i++)
for(int o=7;o >=0;o--)
{
if(ch & 1<<o)
bin.bit[abs(o-7)]= true;
else
bin.bit[abs(o-7)]= false;
}
}


May I ask what advantage d_eq(x,y) has compared to x==y?

you aren't able to use the operator "==" with floating-point numbers
"it's not a precision method"
watch the standard for more info or check this link

http://www.cprogramming.com/tutorial/floating_point/understanding_floating_point.html

and

http://en.wikipedia.org/wiki/IEEE_floating-point_standard

d_eq compare each bit so it's very precision
try that code

double x=215.256487876545;
double y=215.256487876545;

cout << d_eq(x,y);

and then try

double x=215.256487876545;
double y=215.2564878765449; // i change only the last number and
add another in the fraction

cout << d_eq(x,y);

you will watch the precision
Also, what do you gain compared to something like this

template < typename T >
bool equal_representation ( T const & lhs, T const & rhs ) {
unsigned char const * lhs_iter =
static_cast< unsigned char const * >
( static_cast< void const * >( &lhs ) );
unsigned char const * rhs_iter =
static_cast< unsigned char const * >
( static_cast< void const *>( &rhs ) );
return ( std::equal( lhs_iter, lhs_iter+sizeof(T), rhs_iter ) );

}

Here the question is: what do you gain from taking the bytes apart and
looking at each bit individually? Just comaring the bytes should be
sufficient.







Have you tried whether the d_eq() method will give you the desired results?
I would strongly doubt it.
absolutely , as you see in microsoft msdn code you must limit the
equality precision by

#define EPSILON 0.0001 // Define your own tolerance

in d_eq() you don't need for that just put any numbers
the function d_eq() as i thought is very important in advanced math
application when you need
for high precision like
the number 215.256487876545 not equal to 215.2564
 
V

Virtual_X

Virtual_X wrote:
Virtual_X wrote:
As in IEEE754
double consist of
sign bit
11 bits for exponent
52 bits for fraction
i write this code to print double parts as it explained in ieee754
i want to know if the code contain any bug , i am still c++ beginner
#include <iostream>
using namespace std;
struct byte
{
bool bit[8]; // 8 = sizeof(double);
What a misleading comment! struct is called 'byte' What does the
size of the array (8) have to do with the size of 'double'? It is
a pure coincidence, isn't it?
sorry i don't know what you exactly mean
but i think the remain code will explain why i make array(8)
"because byte = 8 bits"
Whenever you write your code, remember that it's going to be read by
somebody at some point. If not, if you write your code once and never
let anybody (even yourself) look at it again, then why put any comments
in it at all?
The declaration of the 'bit' member is
bool bit[8];
The comment right next to it is
// 8 = sizeof(double)
Does that mean that the '8' in the declaration is used because on your
system 'sizeof(double)' yields 8? That's how I am reading it.
that was a mistake
i change the code and forget to remove the comment , sorry :)
BTW, not all systems that support IEEE 754 double have their 'byte'
equal to 8 bits. So, your program is only portable to the systems
that share the size of 'char' with yours.
i think the code can be portable if we use sizeof sothat we can know
the size of double
and for unsigned char may be we can change it by bool "i didn't try
that" which always 1 byte
V
i have write another powerful function "as i thought :)" to check
double equality with very high
precision because it check equality for every bit instead of the
"Microsoft msdn method"
here's my function "depend on the pb()"
bool d_eq(double x,double y)
{
byte bx[8];
byte by[8];
pb(reinterpret_cast<unsigned char*>(&x),bx);
pb(reinterpret_cast<unsigned char*>(&y),by);
for(int i=0;i < 8;i++)
for(int o=0;o < 8;o++)
if (bx.bit[o] != by.bit[o]) return false;

return true;

and Microsoft msdn method
#define EPSILON 0.0001 // Define your own tolerance
#define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))
int main() {
float a, b, c;
a = 1.345f;
b = 1.123f;
c = a + b;
// if (FLOAT_EQ(c, 2.468)) // Remove comment for correct result
if (c == 2.468) // Comment this line for correct result
printf_s("They are equal.\n");
else
printf_s("They are not equal! The value of c is %13.10f "
"or %f",c,c);

you can find it herehttp://msdn2.microsoft.com/en-us/library/c151dt3s(VS.80).aspx
i alway thought that C/C++ really powerful- Hide quoted text -
- Show quoted text -

Unless I am missing something, your method is attempting the
equivalent of the built in == operator, which should never ever be
used to check equality on floating point types. Because floating
points are always rounded to the best binary representation.


not it's a new idea for floating-point numbers equality not based on
the operator "=="
it's instead compare each bit in the both variable
i write it because i know that the operator "==" can't used with
floating-point numbers
float x = 0.01f * 10.0f;
if( x == 0.1f )
{
// Will not always return true!!!

}

i know that please read my function carefuly to see what it exactly do
and watch that it depend on the first function "pb()"
Hence the Microsoft method you found where some threshhold is used.
Most people seem to code thier own equality method that takes two
doubles and a threshold as parameters so you can check if the two
doubles are "close enough" to each other in the context they are used.
This isn't specific to MS or Linux environments, I've seen such
methods done in both. You wouldn't necessarilly want to measure feet a
car has traveled around the world to a presision of .00000001, but you
might for say the width of skin cell in centimeters.

i don't check if the two double is close enough and you can test the
function
instead i check if the two doubles are exactly the same "that's very
important in some
advanced math application" and by changing some parts of the code to
use sizeof "to know the double size in bytes" the code will be
portable enough
 
C

Christopher

Virtual_X wrote:
Virtual_X wrote:
As in IEEE754
double consist of
sign bit
11 bits for exponent
52 bits for fraction
i write this code to print double parts as it explained in ieee754
i want to know if the code contain any bug , i am still c++ beginner
#include <iostream>
using namespace std;
struct byte
{
bool bit[8]; // 8 = sizeof(double);
What a misleading comment! struct is called 'byte' What does the
size of the array (8) have to do with the size of 'double'? It is
a pure coincidence, isn't it?
sorry i don't know what you exactly mean
but i think the remain code will explain why i make array(8)
"because byte = 8 bits"
Whenever you write your code, remember that it's going to be read by
somebody at some point. If not, if you write your code once and never
let anybody (even yourself) look at it again, then why put any comments
in it at all?
The declaration of the 'bit' member is
bool bit[8];
The comment right next to it is
// 8 = sizeof(double)
Does that mean that the '8' in the declaration is used because on your
system 'sizeof(double)' yields 8? That's how I am reading it.
that was a mistake
i change the code and forget to remove the comment , sorry :)
BTW, not all systems that support IEEE 754 double have their 'byte'
equal to 8 bits. So, your program is only portable to the systems
that share the size of 'char' with yours.
i think the code can be portable if we use sizeof sothat we can know
the size of double
and for unsigned char may be we can change it by bool "i didn't try
that" which always 1 byte
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
i have write another powerful function "as i thought :)" to check
double equality with very high
precision because it check equality for every bit instead of the
"Microsoft msdn method"
here's my function "depend on the pb()"
bool d_eq(double x,double y)
{
byte bx[8];
byte by[8];
pb(reinterpret_cast<unsigned char*>(&x),bx);
pb(reinterpret_cast<unsigned char*>(&y),by);
for(int i=0;i < 8;i++)
for(int o=0;o < 8;o++)
if (bx.bit[o] != by.bit[o]) return false;
return true;
}
and Microsoft msdn method
#define EPSILON 0.0001 // Define your own tolerance
#define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))
int main() {
float a, b, c;
a = 1.345f;
b = 1.123f;
c = a + b;
// if (FLOAT_EQ(c, 2.468)) // Remove comment for correct result
if (c == 2.468) // Comment this line for correct result
printf_s("They are equal.\n");
else
printf_s("They are not equal! The value of c is %13.10f "
"or %f",c,c);
}
you can find it herehttp://msdn2.microsoft.com/en-us/library/c151dt3s(VS.80).aspx
i alway thought that C/C++ really powerful- Hide quoted text -
- Show quoted text -

Unless I am missing something, your method is attempting the
equivalent of the built in == operator, which should never ever be
used to check equality on floating point types. Because floating
points are always rounded to the best binary representation.

not it's a new idea for floating-point numbers equality not based on
the operator "=="
it's instead compare each bit in the both variable
i write it because i know that the operator "==" can't used with
floating-point numbers


float x = 0.01f * 10.0f;
if( x == 0.1f )
{
// Will not always return true!!!

i know that please read my function carefuly to see what it exactly do
and watch that it depend on the first function "pb()"


Your function does the equivalent of the == operator
Test the above block, replacing == with a call to your d_eq()
and watch your function give you unintended results. If you know
it, then why are you attempting to comprare each bit exactly,
knowing that they will not be exactly the same????

i don't check if the two double is close enough and you can test the
function
instead i check if the two doubles are exactly the same "that's very
important in some
advanced math application" and by changing some parts of the code to
use sizeof "to know the double size in bytes" the code will be
portable enough- Hide quoted text -

- Show quoted text -

I am NOT saying that your function checks if two doubles are close
enough, I am saying that it SHOULD!!! It is not very important in
adcanced math applications, as you say, because any time any math is
performed on a double, the bits are not going to be the same as the
expected result. I challenge you to show me any math application where
the d_eq function has practicle use and behaves as expected.

I am going to guess that you understand that you should not use == for
comparison of two doubles, but MISUNDERSTAND the REASON. I say this
because your function is performing the same action as the == operator
would, it is comparing the bits for equality. If your mother says
"don't put your hand on the stove" and you put your foot there
instead, you are still going to get burned.

If you still feel I am in error, then please present a compilable test
case using your function d_eq, and the == operator, and show how the
results differ, you may present some of this "advanced math" as well.
 
P

Puppet_Sock

Unfortunately, unless something has changed, this is not the
legal use of 'union'. You are allowed to only access the member
that you set. If you initialise it with 'double', you can only
extract the 'double' from there.

I don't think it's illegal. I think it's ill-defined.
That is, there is no promise the compiler will pack
the union the same way every time. It might not line
things up the same way. It might pad differently.

I seem to have a hazy memory of a compiler that
would change how it packed unions depending on
how stuff lined up at memory page boundaries.
So two instances of the same union might line
up differently.

So I don't think you will get a compiler error.
And it will probably work fine *most* of the time.
It's just that it might stop working without warning.

Unless I'm misremembering badly, which has happened.
From time to time.
Socks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top