473,385 Members | 2,210 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

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

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[i] & 1<<o)
bin[i].bit[abs(o-7)]= true;
else
bin[i].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[i];
//still 4 bits
for(int i=0;i<4;i++)
cout << v[1].bit[i];

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[i];

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

Nov 1 '07 #1
29 2914
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?
};

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

bin[i].bit[abs(o-7)] = (ch[i] & (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[i];
//still 4 bits
for(int i=0;i<4;i++)
cout << v[1].bit[i];

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[i];

//print all the remain bits
for(int i=2;i<8;i++)
for(int o=0;o<8;o++)
{
cout << v[i].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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 1 '07 #2
On Nov 1, 6:43 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
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?
};
void pb(unsigned char *ch,byte *bin)
{
for(int i=0;i <=7;i++)
for(int o=7;o >=0;o--)
{
if(ch[i] & 1<<o)
bin[i].bit[abs(o-7)]= true;
else
bin[i].bit[abs(o-7)]= false;

It is much better to just write

bin[i].bit[abs(o-7)] = (ch[i] & (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[i];
//still 4 bits
for(int i=0;i<4;i++)
cout << v[1].bit[i];
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[i];
//print all the remain bits
for(int i=2;i<8;i++)
for(int o=0;o<8;o++)
{
cout << v[i].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

Nov 1 '07 #3
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
Nov 1 '07 #4
On Nov 1, 6:43 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
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"
>
};
void pb(unsigned char *ch,byte *bin)
{
for(int i=0;i <=7;i++)
for(int o=7;o >=0;o--)
{
if(ch[i] & 1<<o)
bin[i].bit[abs(o-7)]= true;
else
bin[i].bit[abs(o-7)]= false;

It is much better to just write

bin[i].bit[abs(o-7)] = (ch[i] & (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[i];
//still 4 bits
for(int i=0;i<4;i++)
cout << v[1].bit[i];
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[i];
//print all the remain bits
for(int i=2;i<8;i++)
for(int o=0;o<8;o++)
{
cout << v[i].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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Nov 1 '07 #5
Laurent D.A.M. MENTEN wrote:
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
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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 1 '07 #6
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 :
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
Nov 1 '07 #7
On Nov 1, 7:05 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Laurent D.A.M. MENTEN wrote:
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;
}
nice idea but you still want to convert the result to 0 and 1
>
wq

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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Nov 1 '07 #8
Virtual_X wrote:
On Nov 1, 6:43 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>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.

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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 1 '07 #9
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...
Nov 1 '07 #10
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!
Nov 1 '07 #11
On Nov 1, 7:15 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Virtual_X wrote:
On Nov 1, 6:43 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
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

Nov 1 '07 #12
On Nov 1, 12:49 pm, Virtual_X <C.BsM....@gmail.comwrote:
On Nov 1, 7:15 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Virtual_X wrote:
On Nov 1, 6:43 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>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- Hide quoted text -

- 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"

Nov 1 '07 #13
On Nov 1, 9:49 am, Virtual_X <C.BsM....@gmail.comwrote:
On Nov 1, 7:15 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Virtual_X wrote:
On Nov 1, 6:43 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>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[i].bit[o] != by[i].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/lib...3s(VS.80).aspx

i alway thought that C/C++ really powerful

Nov 1 '07 #14
On Nov 1, 1:13 pm, Virtual_X <C.BsM....@gmail.comwrote:
On Nov 1, 9:49 am, Virtual_X <C.BsM....@gmail.comwrote:


On Nov 1, 7:15 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Virtual_X wrote:
On Nov 1, 6:43 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
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[i].bit[o] != by[i].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.

Nov 1 '07 #15
Virtual_X wrote:
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[i].bit[o] != by[i].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[i] & 1<<o)
bin[i].bit[abs(o-7)]= true;
else
bin[i].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
Nov 1 '07 #16
On Nov 1, 10:45 am, Kai-Uwe Bux <jkherci...@gmx.netwrote:
Virtual_X wrote:
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[i].bit[o] != by[i].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[i] & 1<<o)
bin[i].bit[abs(o-7)]= true;
else
bin[i].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...ing_point.html

and

http://en.wikipedia.org/wiki/IEEE_fl...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.
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.
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
>
Best

Kai-Uwe Bux

Nov 1 '07 #17
On Nov 1, 10:52 am, Christopher <cp...@austin.rr.comwrote:
On Nov 1, 1:13 pm, Virtual_X <C.BsM....@gmail.comwrote:
On Nov 1, 9:49 am, Virtual_X <C.BsM....@gmail.comwrote:
On Nov 1, 7:15 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Virtual_X wrote:
On Nov 1, 6:43 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>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[i].bit[o] != by[i].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

Nov 1 '07 #18
On Nov 1, 2:43 pm, Virtual_X <C.BsM....@gmail.comwrote:
On Nov 1, 10:52 am, Christopher <cp...@austin.rr.comwrote:


On Nov 1, 1:13 pm, Virtual_X <C.BsM....@gmail.comwrote:
On Nov 1, 9:49 am, Virtual_X <C.BsM....@gmail.comwrote:
On Nov 1, 7:15 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Virtual_X wrote:
On Nov 1, 6:43 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
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[i].bit[o] != by[i].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????

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- 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.

Nov 1 '07 #19
On Nov 1, 11:05 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Laurent D.A.M. MENTEN wrote:
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

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

Nov 1 '07 #20
Virtual_X wrote:
On Nov 1, 10:45 am, Kai-Uwe Bux <jkherci...@gmx.netwrote:
>Virtual_X wrote:
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[i].bit[o] != by[i].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[i] & 1<<o)
bin[i].bit[abs(o-7)]= true;
else
bin[i].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
That is incorrect.
"it's not a precision method"
That is a meaningless statement.
watch the standard
The standard is with me on this issue (operator== test for being equal, and
that's it).
for more info or check this link

http://www.cprogramming.com/tutorial...ing_point.html
That link says (among other things):

... why is it so hard to know when two floats are equal? In one sense, it
really isn't that hard; the == operator will, in fact, tell you if two
floats are exactly equal (i.e., match bit for bit). ...

which seems to agree with me.
and

http://en.wikipedia.org/wiki/IEEE_fl...point_standard
whereas this link is unrelated to C++ as C++ does not require IEEE
conformance.
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
The standard guarantes that you will get the same with operator== provided
the type double on your implementation has the precision required to
distinguish x and y.

I think your d_eq() is a non-portable equivalent of

bool truly_equal ( double lhs, double rhs ) {
double volatile x = lhs;
double volatile y = rhs;
return ( x == y );
}

Here, I hope the volatile causes a write to memory so that any excess
precision that the parameters may have according to [5/10] goes away.

>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.
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
Actually, in advanced math you may need a different precision that 0.00001
but you will practically always want a precision that is below the inherent
precision of the floating point type. Otherwise, it is very very hard to
ensure that loops terminate. Consider, for instance the bisection method
for solving equations implemented like this:

double low = something;
double high = something_else;
while ( ! d_eq( low, high ) ) {
double middle = (low+high) / 2.0;
if ( f(low) and f(middle) have same sign ) {
high = middle;
else {
low = middle;
}
}

It may happen that the loop does not terminate.

That is, why I doubt that your method yields the _desired_ result.
Best

Kai-Uwe Bux
Nov 1 '07 #21
On Nov 1, 11:55 am, Christopher <cp...@austin.rr.comwrote:
On Nov 1, 2:43 pm, Virtual_X <C.BsM....@gmail.comwrote:
On Nov 1, 10:52 am, Christopher <cp...@austin.rr.comwrote:
On Nov 1, 1:13 pm, Virtual_X <C.BsM....@gmail.comwrote:
On Nov 1, 9:49 am, Virtual_X <C.BsM....@gmail.comwrote:
On Nov 1, 7:15 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Virtual_X wrote:
On Nov 1, 6:43 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>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[i].bit[o] != by[i].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????
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- 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.
some advanced math application like the physics simulators all
researches now in that field tend to get a high precision like
manipulation of floating-point numbers check links like

http://crd.lbl.gov/~dhbailey/
http://crd.lbl.gov/~dhbailey/mpdist/
http://www.egenix.com/products/pytho...r/mxNumber.pdf
http://www.myphysicslab.com/index.html
http://www.ode.org/

google it to see more and more in that field

and why when using "Pi" in game development we don't just say Pi=3.14
instead of a high precision floating-point number like
Pi=3.141592653589793238 because that precision definitely affect the
game graphics

if you want to make a good program in that field you must definitely
care about numerical precision

number 2: the code you want to test to check the different between
"d_eq" and "=="

first any time you use "==" will not produce the same result (That not
my talk you can find it in the standard or ask for it"

second: check this example
double x=0.00001;
double y=0.000009 + 0.000001;

if (d_eq(x,y)) cout << "d_eq equivalent\n";
if (x == y) cout << "== equivalent";

this example will show you that you can't rely on "==" for floating-
point equivalently , try test it in different architectures and check
the result

finally may be you are right and may be not
at all thank's for your review

Nov 1 '07 #22
On Nov 1, 12:36 pm, Kai-Uwe Bux <jkherci...@gmx.netwrote:
Virtual_X wrote:
On Nov 1, 10:45 am, Kai-Uwe Bux <jkherci...@gmx.netwrote:
Virtual_X wrote:
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[i].bit[o] != by[i].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[i] & 1<<o)
bin[i].bit[abs(o-7)]= true;
else
bin[i].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

That is incorrect.
"it's not a precision method"

That is a meaningless statement.
watch the standard

The standard is with me on this issue (operator== test for being equal, and
that's it).
for more info or check this link

http://www.cprogramming.com/tutorial...erstanding_flo...

That link says (among other things):

... why is it so hard to know when two floats are equal? In one sense, it
really isn't that hard; the == operator will, in fact, tell you if two
floats are exactly equal (i.e., match bit for bit). ...

which seems to agree with me.
and
http://en.wikipedia.org/wiki/IEEE_fl...point_standard

whereas this link is unrelated to C++ as C++ does not require IEEE
conformance.
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

The standard guarantes that you will get the same with operator== provided
the type double on your implementation has the precision required to
distinguish x and y.

I think your d_eq() is a non-portable equivalent of

bool truly_equal ( double lhs, double rhs ) {
double volatile x = lhs;
double volatile y = rhs;
return ( x == y );
}

Here, I hope the volatile causes a write to memory so that any excess
precision that the parameters may have according to [5/10] goes away.
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.
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

Actually, in advanced math you may need a different precision that 0.00001
but you will practically always want a precision that is below the inherent
precision of the floating point type. Otherwise, it is very very hard to
ensure that loops terminate. Consider, for instance the bisection method
for solving equations implemented like this:

double low = something;
double high = something_else;
while ( ! d_eq( low, high ) ) {
double middle = (low+high) / 2.0;
if ( f(low) and f(middle) have same sign ) {
high = middle;
else {
low = middle;
}
}

It may happen that the loop does not terminate.

That is, why I doubt that your method yields the _desired_ result.

Best

Kai-Uwe Bux
thanks alot
i admit yor are right "i not an expert but just beginner"

Nov 1 '07 #23
[snip]
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"
You are claiming you wrote a function that compares every bit for
equality. Ok, I trust you did that.
Now tell me once again, what does operator == do? It checks every bit
for equality.
Can we please establish that:
"compares every bit for equality" == "compares every bit for
equality"???


[snip]
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
Again. You are saying your function is a "new idea" as opposed to ==,
but they do the same thing! You said so yourself!: "it check equality
for every bit"
operator == also checks every bit for equality!!!

How is "checks every bit for equality" != "it check equality for every
bit", other than some grammar issues??
>http://crd.lbl.gov/~dhbailey/http://...//www.ode.org/

google it to see more and more in that field

and why when using "Pi" in game development we don't just say Pi=3.14
instead of a high precision floating-point number like
Pi=3.141592653589793238 because that precision definitely affect the
game graphics
if you want to make a good program in that field you must definitely
care about numerical precision


Why are you posting web sites and making an argument that is for my
argument?
Yes, we all care about precision.
Yes, alot of applications need high precision.
However, "high precision" != "check every bit for equality"

number 2: the code you want to test to check the different between
"d_eq" and "=="

first any time you use "==" will not produce the same result (That not
my talk you can find it in the standard or ask for it"

second: check this example
double x=0.00001;
double y=0.000009 + 0.000001;

if (d_eq(x,y)) cout << "d_eq equivalent\n";
if (x == y) cout << "== equivalent";

this example will show you that you can't rely on "==" for floating-
point equivalently , try test it in different architectures and check
the result
You are arguing for my argument again: "this example will show that
you can't rely on "==" for floating point equivalently" is exactly
what I am telling you.
The point you are missing is that == is the same as checking every bit
for equality.

Your test case is incomplete.
Where did you state what the expected results are?
What output did you get from your test case to compare with the
expected results?
Where did you prove d_eq works as it is intended?
Where did you prove that d_eq works at all?
I assume you got no output at all from this test case...

finally may be you are right and may be not
at all thank's for your review
Your welcome, however, it seems you think you're the expert. I just
program advanced math and graphics applications for a living.
>From your original post:
"i want to know if the code contain any bug , i am still c++ beginner"

Nov 1 '07 #24
[snip]
thanks alot
i admit yor are right "i not an expert but just beginner"- Hide quoted text -

Do this for me, to clarify things and make certain we both understand
what the other is saying, because I have a feeling there is some
understanding being lost in interpretation of what was typed.

State what your argument is
State what my argument is

Then maybe we can make sense of things a little easier.

Nov 1 '07 #25
On Nov 1, 2:07 pm, Christopher <cp...@austin.rr.comwrote:
thanks alot
i admit yor are right "i not an expert but just beginner"- Hide quoted text -

Do this for me, to clarify things and make certain we both understand
what the other is saying, because I have a feeling there is some
understanding being lost in interpretation of what was typed.

State what your argument is
State what my argument is

Then maybe we can make sense of things a little easier.
thanks for your time , as i say i am just a beginner who want to learn
more
not to show my abilities

Nov 1 '07 #26
On Nov 1, 7:52 pm, Christopher <cp...@austin.rr.comwrote:
On Nov 1, 1:13 pm, Virtual_X <C.BsM....@gmail.comwrote:
Unless I am missing something, your method is attempting the
equivalent of the built in == operator,
Not really, since it will report that -0.0 is not equal to +0.0.
In sum, he will find that 0.0/-1.0 != 0.0/1.0. I don't think
I'd use his method, evern.
which should never ever be used to check equality on floating
point types.
Never is a strong word. You should use == to check for equality
of floating point types anytime you want to check for equality.
Depending on the application, of course, checking for exact
equality might not be what you want, but that's a different
issue.
Because floating points are always rounded to the best binary
representation.
That statement doesn't really mean anything. Machine floating
point values are not real numbers, and their arithmetic doesn't
obey the same rules as real numbers. For example, (a+b)+c is
not necessarily the same thing as a+(b+c). If you're going to
use machine floating point values, you have to understand
machine floating point arithmetic. Sometimes, it means that you
don't want to check for equality. Other times, it means that
equality actually works better than with real numbers. It all
depends---it's just different from the math you learned in high
school.
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.
Most of the time, such "approximately equal" methods are not a
good solution. An equality function which isn't transitive
poses a number of problems of its own. In the end, you have to
understand the problem, do the analysis, and choose the
appropriate method. It requires real understanding; there are
no automatic solutions.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Nov 2 '07 #27
On Nov 1, 9:36 pm, Kai-Uwe Bux <jkherci...@gmx.netwrote:

[...]
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
The standard guarantes that you will get the same with
operator== provided the type double on your implementation has
the precision required to distinguish x and y.
The standard also requires +0.0 to compare equal to -0.0, and
the C99 standard has some requirements concerning NaN when the
implementation uses IEEE. (These will presumably be part of the
next C++ standard as well.)
I think your d_eq() is a non-portable equivalent of
bool truly_equal ( double lhs, double rhs ) {
double volatile x = lhs;
double volatile y = rhs;
return ( x == y );
}
Here, I hope the volatile causes a write to memory so that any
excess precision that the parameters may have according to
[5/10] goes away.
It shouldn't be necessary. You're passing by value, so the
compiler has to initialize the "variables" with the double. It
can, of course, avoid this under the as if rule, but only if the
results are the same.

Not all compilers get this right, of course, and volatile might
help if you're trying to work around a compiler bug.

--
James Kanze (GABI Software) mailto:ja*********@gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34

Nov 2 '07 #28
On Nov 1, 9:13 pm, Puppet_Sock <puppet_s...@hotmail.comwrote:
On Nov 1, 11:05 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Laurent D.A.M. MENTEN wrote:
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.
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.
It's undefined behavior. The compiler might hide information
concerning the last assigned element of the union somewhere,
check it when you read, and reformat your hard disk if you read
anything other than the last element written.

Since it is undefined behavior, a compiler is free to do
anything with it. Including define it for that compiler. I
believe that some compilers (e.g. g++) do define things in a way
as to allow accessing a different element than the last one
accessed to work.

There is, of course, a second problem with the original code:
how the compiler lays out bit fields is very implementation
dependent, and in fact does vary greatly from one compiler to
the next. Given the definition of double_bits, above, some
compilers will put the sign in the top bit, others in the lowest
bit, and some will put fraction in a different word than
exponent and sign. Using bit fields for this sort of thing is
far from portable.

The only more or less portable way of doing this is to use memcpy:

double value ;
uint_64 asUInt ;
memcpy( &asUInt, &value, sizeof( double ) ) ;
std::cout << "sign : " << ((asUInt >63) & 0x1 <<
std::endl ;
std::cout << "exponent : " << ((asUInt >52) & 0x7FF <<
std::endl ;
std::cout << "mantissa : "
<< (((asUInt ) & 0X000FFFFFFFFFFFFFULL)
| ((asUInt & 0x7FFFFFFFFFFFFFFULL) == 0
? 0 : 0x0010000000000000ULL))
<< std::endl ;

Of course, even this still depends on the implementation 1)
using IEEE format, 2) having uint_64 and 3) supporting long
long, none of which are required by the standard.
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.
That definitely wouldn't be conformant. Nor even usable: what
happened when you had a pointer to the union, and tried to use
it in a different compilation unit.
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.
I've used compilers which would optimize strangely in such
cases. For example, which would detect that you never read the
value written into x.value (since reading x.bits doesn't count,
according to the standard), and so suppressed the assignment.
The company from which I bought the compiler (Microsoft) is
still in business, and in fact, not doing too badly, although
I'm pretty sure that its current products do not use the
original code base. And according to the standard, it's a
legitimate optimization.

According to the standard, the "preferred" way of doing such
type punning is to use reinterpret_cast. Presumably, a compiler
should turn off all optimization when it sees a
reinterpret_cast. Except, of course, that unlike the above, the
results of a reinterpret_cast can span translation unit
boundaries, so the compiler might not see that a
reinterpret_cast was involved. And it's still formally
implementation defined (and doesn't always work with g++).

It's also possible to get the values for the mantissa and the
exponent by means of functions like frexp. Off hand, this
sounds (or sounded to me) unwieldy and slow, but when I actually
tried, it turned out to be not that complicated, and
surprisingly rapid, at least under Solaris on a Sun Sparc.

--
James Kanze (GABI Software) mailto:ja*********@gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34

Nov 2 '07 #29
Virtual_X <C.*******@gmail.comwrites:
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
See

http://frank.harvard.edu/~coldwell/ieeefloat.hh

Chip

--
Charles M. "Chip" Coldwell
"Turn on, log in, tune out"
Somerville, Massachusetts, New England
Nov 2 '07 #30

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

242
by: James Cameron | last post by:
Hi I'm developing a program and the client is worried about future reuse of the code. Say 5, 10, 15 years down the road. This will be a major factor in selecting the development language. Any...
143
by: suri | last post by:
Hello I downloaded glibc and tried looking for the code that implements the sine function i couldnt find the file. i went to the math directory and found math.h.. i guess that needs to be...
289
by: napi | last post by:
I think you would agree with me that a C compiler that directly produces Java Byte Code to be run on any JVM is something that is missing to software programmers so far. With such a tool one could...
33
by: Daniel Fadlun | last post by:
Is there a bigger, mathematical, data type in C than the double (64 bit) one or the old long double (80 bit)? I'd like to add precision to my mathematical application, but I can't figure out how....
25
by: Alvin Bruney | last post by:
C# is great but it does have some short comings. Here, I examine one of them which I definitely think is a shortcoming. Coming from C++, there seems to be no equivalent in C# to separate code...
17
by: Mark | last post by:
I must create a routine that finds tokens in small, arbitrary VB code snippets. For example, it might have to find all occurrences of {Formula} I was thinking that using regular expressions...
5
by: Avi Kak | last post by:
Folks, Does regular expression processing in Python allow for executable code to be embedded inside a regular expression? For example, in Perl the following two statements $regex =...
6
by: seb | last post by:
Hi, I am using pygtk for the first times. I am wondering what would be the best "pattern" to interface pygtk with a thread. The thread is collecting informations (over the network for...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.