473,396 Members | 2,011 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,396 software developers and data experts.

convert binary to decimal in template at compiler time.

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.

Sep 12 '07 #1
9 3447
"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.

Sep 12 '07 #2
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? ;)

Sep 12 '07 #3
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
Sep 12 '07 #4
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?
Sep 12 '07 #5
On Sep 12, 10:08 pm, Kai-Uwe 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.
Sep 12 '07 #6
Old Wolf wrote:
On Sep 12, 10:08 pm, Kai-Uwe 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

Kai-Uwe Bux
Sep 12 '07 #7
On Sep 12, 6:08 pm, Kai-Uwe 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.

Sep 13 '07 #8
Leo jay wrote:
On Sep 12, 6:08 pm, Kai-Uwe 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

Kai-Uwe Bux
Sep 13 '07 #9
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
Sep 13 '07 #10

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

Similar topics

1
by: ferran | last post by:
Hi, does anybody know how to convert in C++ from base 10 to any other base without loosing the decimal part of the actual value? I came up with this algorithm to convert from decimal to any base...
5
by: Ruben Campos | last post by:
Some questions about this code: template <typename T> class MyTemplate; template <typename T> MyTemplate <T> operator- (const MyTemplate <T> & object); template <typename T> MyTemplate <T>...
4
by: jaijai_kumar | last post by:
Select Cast('100.1234' as float) give me the result 100.1234 Now when I convert it back to char I want exactly 100.1234 Select Convert(char(100),Cast('100.1234' as float)) Gives me 100.123 (Here...
2
by: yxq | last post by:
There are 8 bytes binary value stored date and time in Registry. 84 8B D7 DF 8B 28 C5 01 I want to convert the binary value to date using VB.NET. Dim a As FILETIME a.dwHighDateTime = 29698187...
13
by: Jason | last post by:
Could someone here show me how I would write a vb program to convert decimal ip address to binary? For example a small form with a convert button and a label for the result and a textbox for the...
5
by: Ray | last post by:
I have a table with some audit date and time columns. Problem is the developer who stored the data left them as DECIMAL type instead of DATE and TIME. Is there a way I can convert the DECIMAL type...
4
by: QQ | last post by:
Hello unsigned char a; the a represents a 4-bit binary, a represents another 3-bit binary. I'd like to convert a into a decimal. For instance if {a a a a the decimal should be 5
7
by: elliotng.ee | last post by:
I have a text file that contains a header 32-bit binary. For example, the text file could be: %%This is the input text %%test.txt Date: Tue Dec 26 14:03:35 2006...
28
by: FAQ server | last post by:
----------------------------------------------------------------------- FAQ Topic - How do I convert a Number into a String with exactly 2 decimal places?...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

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.