Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > convert binary to decimal in template at compiler time.

Reply
Thread Tools

convert binary to decimal in template at compiler time.

 
 
Leo jay
Guest
Posts: n/a
 
      09-12-2007
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.

 
Reply With Quote
 
 
 
 
Jim Langston
Guest
Posts: n/a
 
      09-12-2007
"Leo jay" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) 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.



 
Reply With Quote
 
 
 
 
Leo jay
Guest
Posts: n/a
 
      09-12-2007
On Sep 12, 5:42 pm, "Jim Langston" <(E-Mail Removed)> wrote:
>
> 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?

 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      09-12-2007
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

Kai-Uwe Bux
 
Reply With Quote
 
Greg Comeau
Guest
Posts: n/a
 
      09-12-2007
In article <(E-Mail Removed). com>,
Leo jay <(E-Mail Removed)> wrote:
>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?
 
Reply With Quote
 
Old Wolf
Guest
Posts: n/a
 
      09-12-2007
On Sep 12, 10:08 pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:
> 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.


 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      09-12-2007
Old Wolf wrote:

> On Sep 12, 10:08 pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:
>> 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

Kai-Uwe Bux
 
Reply With Quote
 
Leo jay
Guest
Posts: n/a
 
      09-13-2007
On Sep 12, 6:08 pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:
> 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.



 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      09-13-2007
Leo jay wrote:

> On Sep 12, 6:08 pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:
>> 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

Kai-Uwe Bux
 
Reply With Quote
 
Barry
Guest
Posts: n/a
 
      09-13-2007
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how to convert from Decimal('1.23456789') to Decimal('1.234') valpa Python 11 03-24-2009 07:11 AM
Error: Cannot convert Decimal("0.0000") to Decimal Vitaliy Python 1 05-29-2008 10:36 AM
convert a binary into decimal QQ C Programming 4 03-23-2006 05:00 AM
Convert decimal number in binary number makok VHDL 1 02-23-2004 06:04 PM
Convert a binary value to unsigned decimal value Golan C Programming 7 12-08-2003 10:20 PM



Advertisments