457,733 Members | 846 Online Need help? Post your question and get tips & solutions from a community of 457,733 IT Pros & Developers. It's quick & easy.

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

 P: n/a 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 using namespace std; struct byte { bool bit; // 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<(&x),v); //Printing the signbit cout << "The sign bit\n" << v.bit << 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.bit[i]; //still 4 bits for(int i=0;i<4;i++) cout << v.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.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 Replies

 P: n/a 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 using namespace std; struct byte { bool bit; // 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<(&x),v); //Printing the signbit cout << "The sign bit\n" << v.bit << 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.bit[i]; //still 4 bits for(int i=0;i<4;i++) cout << v.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.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

 P: n/a On Nov 1, 6:43 am, "Victor Bazarov" using namespace std; struct byte { bool bit; // 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<(&x),v); //Printing the signbit cout << "The sign bit\n" << v.bit << 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.bit[i]; //still 4 bits for(int i=0;i<4;i++) cout << v.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.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

 P: n/a My personal taste goes to some code like this one: #include 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

 P: n/a On Nov 1, 6:43 am, "Victor Bazarov" using namespace std; struct byte { bool bit; // 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<(&x),v); //Printing the signbit cout << "The sign bit\n" << v.bit << 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.bit[i]; //still 4 bits for(int i=0;i<4;i++) cout << v.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.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

 P: n/a Laurent D.A.M. MENTEN wrote: My personal taste goes to some code like this one: #include 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

 P: n/a 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 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

 P: n/a On Nov 1, 7:05 am, "Victor Bazarov" 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

 P: n/a 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

 P: n/a 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

 P: n/a 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; byte by; pb(reinterpret_cast(&x),bx); pb(reinterpret_cast(&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 = 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< 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

 P: n/a On Nov 1, 10:45 am, Kai-Uwe Bux (&x),bx); pb(reinterpret_cast(&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 = 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< 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

 P: n/a On Nov 1, 11:05 am, "Victor Bazarov" 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

 P: n/a Virtual_X wrote: On Nov 1, 10:45 am, Kai-Uwe Bux 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; byte by; pb(reinterpret_cast(&x),bx); pb(reinterpret_cast(&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 = 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<Also, what do you gain compared to something like thistemplate < 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 andlooking at each bit individually? Just comaring the bytes should besufficient. 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 desiredresults? 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

 P: n/a On Nov 1, 12:36 pm, Kai-Uwe Bux (&x),bx); pb(reinterpret_cast(&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 = 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< 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

 P: n/a [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

 P: n/a On Nov 1, 2:07 pm, Christopher

 P: n/a On Nov 1, 7:52 pm, Christopher

 P: n/a On Nov 1, 9:36 pm, Kai-Uwe Bux 