i'd like to implement a class template to convert binary numbers to
decimal at compile time.
and my test cases are:
BOOST_STATIC_ASSERT((bin<1111,1111,1111,1111>::val ue == 65535));
BOOST_STATIC_ASSERT((bin<1111>::value == 15));
BOOST_STATIC_ASSERT((bin<0>::value == 0));
BOOST_STATIC_ASSERT((bin<1010, 0011>::value == 163));
you can find my implementation at: http://pastebin.org/2271
the first three cases were ok, but the last one failed, because,
compiler will parse 0011
as a octal number 9, instead of decimal number 11 because of the
leading 0s.
to resolve this, i defined 4 macros:
#define BIN1(a) bin<9##a>::value
#define BIN2(a, b) bin<9##a, 9##b>::value
#define BIN3(a, b, c) bin<9##a, 9##b, 9##c>::value
#define BIN4(a, b, c, d) bin<9##a, 9##b, 9##c, 9##d>::value
these macros could pass the last test case, but it's not good enough
that i have to specify how many numbers i will input.
is there any elegant way to resolve this?
thanks in advance. 9 3149
"Leo jay" <Py***********@gmail.comwrote in message
news:11**********************@w3g2000hsg.googlegro ups.com...
i'd like to implement a class template to convert binary numbers to
decimal at compile time.
and my test cases are:
BOOST_STATIC_ASSERT((bin<1111,1111,1111,1111>::val ue == 65535));
BOOST_STATIC_ASSERT((bin<1111>::value == 15));
BOOST_STATIC_ASSERT((bin<0>::value == 0));
BOOST_STATIC_ASSERT((bin<1010, 0011>::value == 163));
you can find my implementation at: http://pastebin.org/2271
the first three cases were ok, but the last one failed, because,
compiler will parse 0011
as a octal number 9, instead of decimal number 11 because of the
leading 0s.
to resolve this, i defined 4 macros:
#define BIN1(a) bin<9##a>::value
#define BIN2(a, b) bin<9##a, 9##b>::value
#define BIN3(a, b, c) bin<9##a, 9##b, 9##c>::value
#define BIN4(a, b, c, d) bin<9##a, 9##b, 9##c, 9##d>::value
these macros could pass the last test case, but it's not good enough
that i have to specify how many numbers i will input.
is there any elegant way to resolve this?
thanks in advance.
Iteratore over the binary string backwards, raising by power of 2 and adding
up.
Untested code, presuming MyString contains binary string such as "10010010"
or whatever.
int value = 0;
int Multiplier = 1;
for ( int i = MyString.size()  1; i >= 0; i )
{
if ( MyString[i] == '1' )
value += Multiplier;
Multiplier *= 2;
}
At the end value should have the binary value.
Now, since you have a decimal number you are trying to represent a binary
number with (not a good idea, you should go with strings or bit map) you
need to get it to a string. Easy method, use stringstream.
On Sep 12, 5:42 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
>
At the end value should have the binary value.
Now, since you have a decimal number you are trying to represent a binary
number with (not a good idea, you should go with strings or bit map) you
need to get it to a string. Easy method, use stringstream.
thanks for your reply, i know parsing string is a good idea.
but i want to do it with templates at compile time.
the best way to learn something is to use it often, isn't it? ;)
Leo jay wrote:
i'd like to implement a class template to convert binary numbers to
decimal at compile time.
and my test cases are:
BOOST_STATIC_ASSERT((bin<1111,1111,1111,1111>::val ue == 65535));
BOOST_STATIC_ASSERT((bin<1111>::value == 15));
BOOST_STATIC_ASSERT((bin<0>::value == 0));
BOOST_STATIC_ASSERT((bin<1010, 0011>::value == 163));
you can find my implementation at: http://pastebin.org/2271
the first three cases were ok, but the last one failed, because,
compiler will parse 0011
as a octal number 9, instead of decimal number 11 because of the
leading 0s.
to resolve this, i defined 4 macros:
#define BIN1(a) bin<9##a>::value
#define BIN2(a, b) bin<9##a, 9##b>::value
#define BIN3(a, b, c) bin<9##a, 9##b, 9##c>::value
#define BIN4(a, b, c, d) bin<9##a, 9##b, 9##c, 9##d>::value
these macros could pass the last test case, but it's not good enough
that i have to specify how many numbers i will input.
is there any elegant way to resolve this?
Not really elegant, but straight forward and without macros:
#include <boost/static_assert.hpp>
template < unsigned int n >
struct bin_one;
template <>
struct bin_one< (unsigned int)(1) {
static unsigned int const value = 0;
};
template <>
struct bin_one<0000{
static unsigned int const value = 0;
};
template <>
struct bin_one<0001{
static unsigned int const value = 1;
};
template <>
struct bin_one<0010{
static unsigned int const value = 2;
};
template <>
struct bin_one<0011{
static unsigned int const value = 3;
};
template <>
struct bin_one<0100{
static unsigned int const value = 4;
};
template <>
struct bin_one<0101{
static unsigned int const value = 5;
};
template <>
struct bin_one<0110{
static unsigned int const value = 6;
};
template <>
struct bin_one<0111{
static unsigned int const value = 7;
};
template <>
struct bin_one<1000{
static unsigned int const value = 8;
};
template <>
struct bin_one<1001{
static unsigned int const value = 9;
};
template <>
struct bin_one<1010{
static unsigned int const value = 10;
};
template <>
struct bin_one<1011{
static unsigned int const value = 11;
};
template <>
struct bin_one<1100{
static unsigned int const value = 12;
};
template <>
struct bin_one<1101{
static unsigned int const value = 13;
};
template <>
struct bin_one<1111{
static unsigned int const value = 15;
};
template < unsigned int a, unsigned int b >
struct bin_two {
static unsigned int const value =
bin_one<a>::value * 16 + bin_one<b>::value;
};
template < unsigned int a, unsigned int b, unsigned int c >
struct bin_three {
static unsigned int const value =
bin_two<a,b>::value * 16 + bin_one<c>::value;
};
template < unsigned int a, unsigned int b, unsigned int c, unsigned int d >
struct bin_four {
static unsigned int const value =
bin_three<a,b,c>::value * 16 + bin_one<d>::value;
};
template < unsigned int a,
unsigned int b = (unsigned int)(1),
unsigned int c = (unsigned int)(1),
unsigned int d = (unsigned int)(1) >
struct bin {
static unsigned int const value =
( b == (unsigned int)(1) ? bin_one<a>::value : 0 )
+
( b != (unsigned int)(1) && c == (unsigned int)(1) ?
bin_two<a,b>::value : 0 )
+
( c != (unsigned int)(1) && d == (unsigned int)(1) ?
bin_three<a,b,c>::value : 0 )
+
( d != (unsigned int)(1) ? bin_four<a,b,c,d>::value : 0 );
};
int main ( void ) {
BOOST_STATIC_ASSERT((bin<1111,1111,1111,1111>::val ue == 65535));
BOOST_STATIC_ASSERT((bin<1111>::value == 15));
BOOST_STATIC_ASSERT((bin<0>::value == 0));
BOOST_STATIC_ASSERT((bin<1010, 0011>::value == 163));
}
Best
KaiUwe Bux
In article <11**********************@w3g2000hsg.googlegroups. com>,
Leo jay <Py***********@gmail.comwrote:
>i'd like to implement a class template to convert binary numbers to decimal at compile time....
This may not be exactly what you're looking for: http://www.comeaucomputing.com/techtalk/#binaryliteral
but perhaps can give you some ideas.

Greg Comeau / 4.3.9 with C++0xisms now in beta!
Comeau C/C++ ONLINE == http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
On Sep 12, 10:08 pm, KaiUwe Bux <jkherci...@gmx.netwrote:
template < unsigned int a,
unsigned int b = (unsigned int)(1),
unsigned int c = (unsigned int)(1),
unsigned int d = (unsigned int)(1) >
struct bin {
static unsigned int const value =
( b == (unsigned int)(1) ? bin_one<a>::value : 0 )
+
( b != (unsigned int)(1) && c == (unsigned int)(1) ?
bin_two<a,b>::value : 0 )
+
( c != (unsigned int)(1) && d == (unsigned int)(1) ?
bin_three<a,b,c>::value : 0 )
+
( d != (unsigned int)(1) ? bin_four<a,b,c,d>::value : 0 );
};
None of those casts is required. 1 will be
converted to unsigned int when used as argument
of a binary operator where the other argument is
unsigned int.
Old Wolf wrote:
On Sep 12, 10:08 pm, KaiUwe Bux <jkherci...@gmx.netwrote:
>template < unsigned int a, unsigned int b = (unsigned int)(1), unsigned int c = (unsigned int)(1), unsigned int d = (unsigned int)(1) > struct bin {
static unsigned int const value = ( b == (unsigned int)(1) ? bin_one<a>::value : 0 ) + ( b != (unsigned int)(1) && c == (unsigned int)(1) ? bin_two<a,b>::value : 0 ) + ( c != (unsigned int)(1) && d == (unsigned int)(1) ? bin_three<a,b,c>::value : 0 ) + ( d != (unsigned int)(1) ? bin_four<a,b,c,d>::value : 0 ); };
None of those casts is required. 1 will be
converted to unsigned int when used as argument
of a binary operator where the other argument is
unsigned int.
True, I just wanted to make the compiler shut up about comparisons between
signed and unsigned types. It did put out tons of warnings.
Best
KaiUwe Bux
On Sep 12, 6:08 pm, KaiUwe Bux <jkherci...@gmx.netwrote:
Not really elegant, but straight forward and without macros:
#include <boost/static_assert.hpp>
template < unsigned int n >
struct bin_one;
template <>
struct bin_one< (unsigned int)(1) {
static unsigned int const value = 0;
};
template <>
struct bin_one<0000{
static unsigned int const value = 0;
};
wow, that's a good idea.
my new version is: http://pastebin.org/2329
any more ideas?
thanks.
Leo jay wrote:
On Sep 12, 6:08 pm, KaiUwe Bux <jkherci...@gmx.netwrote:
>Not really elegant, but straight forward and without macros:
#include <boost/static_assert.hpp>
template < unsigned int n > struct bin_one;
template <> struct bin_one< (unsigned int)(1) {
static unsigned int const value = 0;
};
template <> struct bin_one<0000{
static unsigned int const value = 0;
};
wow, that's a good idea.
my new version is: http://pastebin.org/2329
Well, I changed it a bit and added that stuff to my code base. Here is the
version I finally settled for:
namespace DO_NOT_USE {
template < unsigned long n >
struct bin_one;
template <>
struct bin_one< 65536 {
static unsigned long const value = 0;
};
template <>
struct bin_one<0000{
static unsigned long const value = 0;
};
template <>
struct bin_one<0001{
static unsigned long const value = 1;
};
template <>
struct bin_one<0010{
static unsigned long const value = 2;
};
template <>
struct bin_one<10{
static unsigned long const value = 2;
};
template <>
struct bin_one<0011{
static unsigned long const value = 3;
};
template <>
struct bin_one<11{
static unsigned long const value = 3;
};
template <>
struct bin_one<0100{
static unsigned long const value = 4;
};
template <>
struct bin_one<100{
static unsigned long const value = 4;
};
template <>
struct bin_one<0101{
static unsigned long const value = 5;
};
template <>
struct bin_one<101{
static unsigned long const value = 5;
};
template <>
struct bin_one<0110{
static unsigned long const value = 6;
};
template <>
struct bin_one<110{
static unsigned long const value = 6;
};
template <>
struct bin_one<0111{
static unsigned long const value = 7;
};
template <>
struct bin_one<111{
static unsigned long const value = 7;
};
template <>
struct bin_one<1000{
static unsigned long const value = 8;
};
template <>
struct bin_one<1001{
static unsigned long const value = 9;
};
template <>
struct bin_one<1010{
static unsigned long const value = 10;
};
template <>
struct bin_one<1011{
static unsigned long const value = 11;
};
template <>
struct bin_one<1100{
static unsigned long const value = 12;
};
template <>
struct bin_one<1101{
static unsigned long const value = 13;
};
template <>
struct bin_one<1111{
static unsigned long const value = 15;
};
template < unsigned long a, unsigned long b >
struct bin_two {
static unsigned long const value =
bin_one<a>::value * 16 + bin_one<b>::value;
};
template
< unsigned long a, unsigned long b, unsigned long c, unsigned long d >
struct bin_four {
static unsigned long const value =
bin_two<a,b>::value * 256 + bin_two<c,d>::value;
};
template
< unsigned long a, unsigned long b, unsigned long c, unsigned long d,
unsigned long e, unsigned long f, unsigned long g, unsigned long h >
struct bin_eight {
static unsigned long const value =
bin_four<a,b,c,d>::value * 65536 + bin_four<e,f,g,h>::value;
};
} // namespace DO_NOT_USE
template
< unsigned long a,
unsigned long b = 65536,
unsigned long c = 65536,
unsigned long d = 65536,
unsigned long e = 65536,
unsigned long f = 65536,
unsigned long g = 65536,
unsigned long h = 65536 >
class binary_literal {
static unsigned long const mask = 65536;
public:
static unsigned long const value =
DO_NOT_USE::bin_eight<a,b,c,d,e,f,g,h>::value >>
(((b&mask)+(c&mask)+(d&mask)+(e&mask)+(f&mask)+(g& mask)+(h&mask))/16384);
};
Best
KaiUwe Bux
Leo jay wrote:
i'd like to implement a class template to convert binary numbers to
decimal at compile time.
and my test cases are:
BOOST_STATIC_ASSERT((bin<1111,1111,1111,1111>::val ue == 65535));
BOOST_STATIC_ASSERT((bin<1111>::value == 15));
BOOST_STATIC_ASSERT((bin<0>::value == 0));
BOOST_STATIC_ASSERT((bin<1010, 0011>::value == 163));
you can find my implementation at: http://pastebin.org/2271
the first three cases were ok, but the last one failed, because,
compiler will parse 0011
as a octal number 9, instead of decimal number 11 because of the
leading 0s.
to resolve this, i defined 4 macros:
#define BIN1(a) bin<9##a>::value
#define BIN2(a, b) bin<9##a, 9##b>::value
#define BIN3(a, b, c) bin<9##a, 9##b, 9##c>::value
#define BIN4(a, b, c, d) bin<9##a, 9##b, 9##c, 9##d>::value
these macros could pass the last test case, but it's not good enough
that i have to specify how many numbers i will input.
is there any elegant way to resolve this?
combining your implementation and Kai's from else thread
// specialization for byte starting with 0
// 0000 and 0001 is no need specialized
template <>
struct bin1 <0010>
{
static const unsigned int value = 2u;
};
template <>
struct bin1 <0011>
{
static const unsigned int value = 3u;
};
template <>
struct bin1 <0100>
{
static const unsigned int value = 4u;
};
template <>
struct bin1 <0101>
{
static const unsigned int value = 5u;
};
template <>
struct bin1 <0110>
{
static const unsigned int value = 6u;
};
template <>
struct bin1 <0111>
{
static const unsigned int value = 7u;
};
then
bin<0010, 0001>::value == bin<10, 1>::value

Thanks
Barry This discussion thread is closed Replies have been disabled for this discussion. Similar topics
1 post
views
Thread by ferran 
last post: by

5 posts
views
Thread by Ruben Campos 
last post: by

4 posts
views
Thread by jaijai_kumar 
last post: by

2 posts
views
Thread by yxq 
last post: by

13 posts
views
Thread by Jason 
last post: by

5 posts
views
Thread by Ray 
last post: by

4 posts
views
Thread by QQ 
last post: by

7 posts
views
Thread by elliotng.ee 
last post: by

28 posts
views
Thread by FAQ server 
last post: by
          