473,396 Members | 1,748 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.

std::binary(n)

Here's something I put together just now; whilst I don't know enough
to make this act the same way std::hex and std::dec does, this works
quite well enough for me, but I think I could improve on this.
Suggestions and flames both welcome. To use, try this:

unsigned char ch = 0x80;
std::cout << std::binary(ch) << "\n";

So, here's the code as follows:

namespace std
{
template <typename _T>
struct _binary { std::string _digits; };

template <typename T>
inline _binary<T> binary(T n)
{
_binary<T> __binary;
int bits = sizeof(n);

switch (bits)
{
case 1 : bits = 7; break;
case 2 : bits = 15; break;
case 4 : bits = 31; break;
// add more if necessary
}

for (int i = bits; i >= 0; i--)
{
if ((n >> i) & 1)
__binary._digits.append("1");
else
__binary._digits.append("0");
}

return __binary;
}

template <typename T>
ostream& operator<<(ostream& stream, _binary<T> __binary)
{
stream << __binary._digits;
return stream;
}
}
--
http://www.munted.org.uk

Take a nap, it saves lives.
May 30 '06 #1
18 7689
Alex Buell wrote:
Here's something I put together just now; whilst I don't know enough
to make this act the same way std::hex and std::dec does, this works
quite well enough for me, but I think I could improve on this.
Suggestions and flames both welcome. To use, try this:
You mean, other than the fact that you're adding to namespace std and
using identifiers reserved to the implementation under 17.4.3.1?
unsigned char ch = 0x80;
std::cout << std::binary(ch) << "\n";

So, here's the code as follows:

namespace std
{
template <typename _T>
struct _binary { std::string _digits; };

template <typename T>
inline _binary<T> binary(T n)
{
_binary<T> __binary;
int bits = sizeof(n);

switch (bits)
{
case 1 : bits = 7; break;
case 2 : bits = 15; break;
case 4 : bits = 31; break;
// add more if necessary
}

for (int i = bits; i >= 0; i--)
{
if ((n >> i) & 1)
__binary._digits.append("1");
else
__binary._digits.append("0");
}

return __binary;
}

template <typename T>
ostream& operator<<(ostream& stream, _binary<T> __binary)
{
stream << __binary._digits;
return stream;
}
}

May 30 '06 #2
On Tue, 30 May 2006 23:11:18 GMT, I waved a wand and this message
magically appeared:
Here's something I put together just now; whilst I don't know enough
to make this act the same way std::hex and std::dec does, this works
quite well enough for me, but I think I could improve on this.
Suggestions and flames both welcome. To use, try this:

You mean, other than the fact that you're adding to namespace std and
using identifiers reserved to the implementation under 17.4.3.1?


Good point, guess I should read up on 17.4.3.1.
--
http://www.munted.org.uk

Take a nap, it saves lives.
May 31 '06 #3
On Tue, 30 May 2006 23:11:18 GMT, I waved a wand and this message
magically appeared:
Here's something I put together just now; whilst I don't know enough
to make this act the same way std::hex and std::dec does, this works
quite well enough for me, but I think I could improve on this.
Suggestions and flames both welcome. To use, try this:

You mean, other than the fact that you're adding to namespace std and
using identifiers reserved to the implementation under 17.4.3.1?


Umm, in which book and which edition would that be? If it's the C++
Programming Language book, 17.4.3 only relates to sets.
--
http://www.munted.org.uk

Take a nap, it saves lives.
May 31 '06 #4
Alex Buell wrote:
Here's something I put together just now; whilst I don't know enough
to make this act the same way std::hex and std::dec does, this works
quite well enough for me, but I think I could improve on this.
Suggestions and flames both welcome. To use, try this:

unsigned char ch = 0x80;
std::cout << std::binary(ch) << "\n";

So, here's the code as follows:

namespace std
{
template <typename _T>
struct _binary { std::string _digits; };

template <typename T>
inline _binary<T> binary(T n)
{
_binary<T> __binary;
int bits = sizeof(n);

switch (bits)
{
case 1 : bits = 7; break;
case 2 : bits = 15; break;
case 4 : bits = 31; break;
// add more if necessary
}

for (int i = bits; i >= 0; i--)
{
if ((n >> i) & 1)
__binary._digits.append("1");
else
__binary._digits.append("0");
}

return __binary;
}

template <typename T>
ostream& operator<<(ostream& stream, _binary<T> __binary)
{
stream << __binary._digits;
return stream;
}
}
--
http://www.munted.org.uk

Take a nap, it saves lives.

" Suggestions and flames both welcome. To use, try this: "
First do not add something to namespace std - this is only for standard
libs and your code not yet become part of the standard..
I think that first you have to consider that there is a standard
container for this - bitset.
second there are better ways (speed wise at least) that you can choose
in implementing this so I think that you have to rethink what you were
doing..
good luck anyways and take a nup :)

May 31 '06 #5
Alex Buell wrote:
On Tue, 30 May 2006 23:11:18 GMT, I waved a wand and this message
magically appeared:
> Here's something I put together just now; whilst I don't know enough
> to make this act the same way std::hex and std::dec does, this works
> quite well enough for me, but I think I could improve on this.
> Suggestions and flames both welcome. To use, try this:
>

You mean, other than the fact that you're adding to namespace std and
using identifiers reserved to the implementation under 17.4.3.1?


Umm, in which book and which edition would that be? If it's the C++
Programming Language book, 17.4.3 only relates to sets.


He was refering to the standard itself:

Adding to namespace std:

[17.4.3.1/1]
It is undefined for a C + + program to add declarations or definitions to
namespace std or namespaces within namespace std unless otherwise
specified. A program may add template specializations for any standard
library template to namespace std. Such a specialization (complete or
partial) of a standard library template results in undefined behavior
unless the declaration depends on a user-defined name of external linkage
and unless the specialization meets the standard library requirements for
the original template.
Reserved identifiers:

[17.4.3.1.2/1]
Certain sets of names and function signatures are always reserved to the
implementation:
? Each name that contains a double underscore (__) or begins with an
underscore followed by an uppercase letter (2.11) is reserved to the
implementation for any use.
? Each name that begins with an underscore is reserved to the implementation
for use as a name in the global namespace.
Best

Kai-Uwe Bux
May 31 '06 #6
On Wed, 31 May 2006 01:43:50 -0400, I waved a wand and this message
magically appeared:
Umm, in which book and which edition would that be? If it's the C++
Programming Language book, 17.4.3 only relates to sets.


He was refering to the standard itself:


OK, thanks. I've now removed it from std namespace and put it in its
own namespace. But really we could do with something like std::bin. And
is there a way to have binary numbers? Something like:

unsigned char n = 01010101b;

Would be nice, but I'll make do with hex digits.
--
http://www.munted.org.uk

Take a nap, it saves lives.
May 31 '06 #7
Alex Buell wrote:
template <typename _T>
Don't use identifiers with leading underscores -- those are reserved.
struct _binary { std::string _digits; };
template <typename T>
inline _binary<T> binary(T n)
{
Umm... why isn't all this work being done in a constructor?
_binary<T> __binary;
int bits = sizeof(n);
sizeof returns the size in characters (usu, but not alw, bytes), not
bits. Seems you already know this, based on your usage in the switch
statement, but it's a really bad idea to change the semantics of a
variable midstream like this. It's just confusing and misleading.
switch (bits)
{
case 1 : bits = 7; break;
case 2 : bits = 15; break;
case 4 : bits = 31; break;
// add more if necessary
}
Ever think of making the computer compute this for you? They're good
at computing stuff. Also, all of these values are off by one, for no
apparent reason.

for (int i = bits; i >= 0; i--)
Another piece of misleading code -- iterating backwards is unusual, and
the fact that you're doing it is easy to miss, which could lead to
unhappy surprises.

If your bit values weren't off by one, you could just do the far more
familiar:
for(int i = 0; i < bits; ++i)
{
if ((n >> i) & 1)
And then change this to
if (n & (1 << i))
__binary._digits.append("1");
else
__binary._digits.append("0");
}
I bet single quotes are faster here.
template <typename T>
ostream& operator<<(ostream& stream, _binary<T> __binary)


Pass by const&, not by value.

Luke

May 31 '06 #8
On 31 May 2006 08:20:23 -0700, I waved a wand and this message
magically appeared:
Don't use identifiers with leading underscores -- those are reserved. Umm... why isn't all this work being done in a constructor? sizeof returns the size in characters (usu, but not alw, bytes), not
bits. Seems you already know this, based on your usage in the switch
statement, but it's a really bad idea to change the semantics of a
variable midstream like this. It's just confusing and misleading. Ever think of making the computer compute this for you? They're good
at computing stuff. Also, all of these values are off by one, for no
apparent reason. Another piece of misleading code -- iterating backwards is unusual,
and the fact that you're doing it is easy to miss, which could lead to
unhappy surprises. If your bit values weren't off by one, you could just do the far more
familiar:
for(int i = 0; i < bits; ++i) And then change this to
if (n & (1 << i)) I bet single quotes are faster here. Pass by const&, not by value.


All this doesn't matter, I've switched to bitsets, as that's a lot
easier to work with.
--
http://www.munted.org.uk

Take a nap, it saves lives.
May 31 '06 #9
Luke Meyers <n.***********@gmail.com> wrote:
sizeof returns the size in characters (usu, but not alw, bytes)


I thought by definition 1 char == 1 byte (though not necessarily
1 "octet" or 8 bits).

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
May 31 '06 #10
Marcus Kwok wrote:
Luke Meyers <n.***********@gmail.com> wrote:
sizeof returns the size in characters (usu, but not alw, bytes)


I thought by definition 1 char == 1 byte (though not necessarily
1 "octet" or 8 bits).


I think the definition of "byte" is well-established (as 8 bits) and
well beyond the jurisdiction of the C++ standard.

Luke

May 31 '06 #11
Alex Buell wrote:
On 31 May 2006 08:20:23 -0700, I waved a wand and this message
magically appeared:


Cute, but kind of defeats the purpose -- if you're going to quote me
(as you should when replying), I'd appreciate attribution.
Umm... why isn't all this work being done in a constructor?

Pass by const&, not by value.


All this doesn't matter, I've switched to bitsets, as that's a lot
easier to work with.


It's lovely that you've switched to bitsets, but I think I gave you
some very useful general C++ tips, so I'm a little dismayed to see you
simply assert that it "doesn't matter." Doing construction in
constructors, passing by const& to avoid expensive copying, writing
clear code, none of this is particular to the problem at hand. It's
just stuff you should do when writing C++.

Luke

May 31 '06 #12
* Luke Meyers:
Marcus Kwok wrote:
Luke Meyers <n.***********@gmail.com> wrote:
sizeof returns the size in characters (usu, but not alw, bytes)

I thought by definition 1 char == 1 byte (though not necessarily
1 "octet" or 8 bits).


I think the definition of "byte" is well-established (as 8 bits) and
well beyond the jurisdiction of the C++ standard.


Nope.

Some languages impose 8-bit bytes.

C and C++ do not. In the C++ standard, the result of sizeof is defined
as the number of bytes, and the size of char is defined as 1 (para
5.3.3/1). Which makes char and byte synonyms in C++. By implication,
since the C++ standard refers down to the C standard, a C++ byte is at
least 8 bits, and in practice all compilers for a given platform use the
same byte size. But a byte can be and is larger than 8 bits on some
systems, especially in the embedded systems world.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 1 '06 #13
On 31 May 2006 16:52:19 -0700, I waved a wand and this message
magically appeared from Luke Meyers:
All this doesn't matter, I've switched to bitsets, as that's a lot
easier to work with.


It's lovely that you've switched to bitsets, but I think I gave you
some very useful general C++ tips, so I'm a little dismayed to see you
simply assert that it "doesn't matter." Doing construction in
constructors, passing by const& to avoid expensive copying, writing
clear code, none of this is particular to the problem at hand. It's
just stuff you should do when writing C++.


I've kept the file around; I'll work on it when I have the time.
--
http://www.munted.org.uk

Take a nap, it saves lives.
Jun 1 '06 #14
On 31 May 2006 16:52:19 -0700, I waved a wand and this message
magically appeared from Luke Meyers:
It's lovely that you've switched to bitsets, but I think I gave you
some very useful general C++ tips, so I'm a little dismayed to see you
simply assert that it "doesn't matter." Doing construction in
constructors, passing by const& to avoid expensive copying, writing
clear code, none of this is particular to the problem at hand. It's
just stuff you should do when writing C++.


Right, here's my latest binary class:

class binary
{
public:
template <typename T>
binary(const T& n)
{
bits = sizeof(n) * 8;
for (int i = 0; i < bits; i++)
{
if (n & (1 << i))
digits.insert(digits.begin(), '1');
else
digits.insert(digits.begin(), '0');
}

if (digits.size() != bits)
throw;
}

friend std::ostream& operator<<(std::ostream& stream, const
binary& bin) {
stream << bin.digits;
return stream;
}

private:
std::string digits;
int bits;
};

--
http://www.munted.org.uk

Take a nap, it saves lives.
Jun 1 '06 #15
Rod
On Wed, 31 May 2006 07:05:42 +0100 Alex Buell <al********@munted.org.uk> wrote:
:> is there a way to have binary numbers? Something like:
:>
:> unsigned char n = 01010101b;
:>
:> Would be nice, but I'll make do with hex digits.

std::bitset

Cheers,
__ Rod.
Jun 1 '06 #16
Alex Buell wrote:
Right, here's my latest binary class:
Hey, much better! Couple of suggested refinements inline, but really
just minor stuff...
bits = sizeof(n) * 8;
If you want to avoid this magic number, and be portable to platforms
with char wider than 8 bits, there's a constant somewhere (in <limits>,
IIRC) which will give you the number of bits in a char.
if (n & (1 << i))
digits.insert(digits.begin(), '1');
else
digits.insert(digits.begin(), '0');
Same thing, less duplication:

digits.insert(digits.begin(), (n&(1<<i)) ? '1' : '0');

Or, for more readability, perhaps something like:

char const digit = (n & (1<<i))
? '1'
: '0';
digits.insert(digits.begin(), digit);
if (digits.size() != bits)
throw;
This is incorrect. You have to throw something. This syntax is only
for rethrowing an existing exception from within a catch block. The
reason the compiler doesn't catch it is because it can't tell whether
you'd actually be reaching this line from within a catch block farther
up the stack.
friend std::ostream& operator<<(std::ostream& stream, const
binary& bin) {
stream << bin.digits;
return stream;
}


Or just:
return stream << bin.digits;

Cheers,
Luke

Jun 1 '06 #17
On 1 Jun 2006 13:21:10 -0700, I waved a wand and this message magically
appeared from Luke Meyers:
If you want to avoid this magic number, and be portable to platforms
with char wider than 8 bits, there's a constant somewhere (in
<limits>, IIRC) which will give you the number of bits in a char.
Yep, it's std::numeric_limits<T>::digits. Thank the Ghods for that, as I
did wonder what I would have to do about architectures that may have
strange ideas about how many bits a type might have.
Same thing, less duplication:

digits.insert(digits.begin(), (n&(1<<i)) ? '1' : '0');
I've been using that a lot lately, didn't think of optimising that in
the code.
if (digits.size() != bits)
throw;


This is incorrect. You have to throw something. This syntax is only
for rethrowing an existing exception from within a catch block. The
reason the compiler doesn't catch it is because it can't tell whether
you'd actually be reaching this line from within a catch block farther
up the stack.


I've implemented a class inherited from std::exception and throw an
exception if there's a mismatch between the bits and the number of
digits generated.
Or just:
return stream << bin.digits;


Hey, cool optimisation! Thanks. Below is the complete class:

class binary
{
public:
class bad_bits : public std::exception
{
virtual const char* what() const throw()
{
return "Number of Bits != Number of digits!";
}
} bad_bits;

template <typename T>
binary(const T& n)
{
bits = std::numeric_limits<T>::digits;
for (int i = 0; i < bits; i++)
digits.insert(digits.begin(), (n & (1 << i)) ?
'1' : '0');

if (digits.size() != bits)
throw bad_bits;
}

friend std::ostream& operator<<(std::ostream& stream, const
binary& bin) {
return stream << bin.digits;
}

private:
std::string digits;
int bits;
};

--
http://www.munted.org.uk

Take a nap, it saves lives.
Jun 1 '06 #18
On Thu, 1 Jun 2006 22:14:18 +0100, I waved a wand and this message
magically appeared from Alex Buell:

I've just done away with the need for the member variable 'bits' by
making it an const and moving it into the constructor.

#include <iostream>
#include <string>
#include <limits>
#include <exception>

class binary
{
public:
class bad_bits : public std::exception
{
virtual const char* what() const throw()
{
return "Number of Bits != Number of digits!";
}
} bad_bits;

template <typename T>
binary(const T& n)
{
const int bits = std::numeric_limits<T>::digits;
for (int i = 0; i < bits; i++)
digits.insert(digits.begin(), (n & (1 << i)) ?
'1' : '0');

if (digits.size() != bits)
throw bad_bits;
}

friend std::ostream& operator<<(std::ostream& stream, const
binary& bin) {
return stream << bin.digits;
}

private:
std::string digits;
};

--
http://www.munted.org.uk

Take a nap, it saves lives.
Jun 2 '06 #19

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

Similar topics

20
by: Christian Stigen Larsen | last post by:
A signed int reserves one bit to signify whether a number is positive or negative. In light of this, a colleague asked me whether there existed an int in C++ that was -0, a zero with the negative...
6
by: Andrew | last post by:
Hi I have a question is there a function in C++ to convert an integer into a Binary number Thanks in Advance Cheers
103
by: Steven T. Hatton | last post by:
§27.4.2.1.4 Type ios_base::openmode Says this about the std::ios::binary openmode flag: *binary*: perform input and output in binary mode (as opposed to text mode) And that is basically _all_ it...
9
by: Gaijinco | last post by:
Is there any way to declare a variable as a binary so that if the variable "var" holds the value of 1001, then ++var = 1010?
2
by: news.online.no | last post by:
Hi all Rather than writing std::binary:functions I thought it would be nice to create a comparison expression directly into the algorithm expression. Typical use is struct Person {...
4
by: nguser3552 | last post by:
Hello everyone, I'm wondering if someone out there knows how in a visual c++ console application how I can do the following, and man I've tried, it seems simple really: I need to open up any...
9
by: Xian | last post by:
Is there a right and proper (tm) way to end a line? Thinking about portability and the mess that the 'wrong' line endings can cause. E.g. std::cout << "Hello World!\n"; or std::cout << "Hello...
3
by: zgfareed | last post by:
My program converts decimal numbers from to binary and hexadecimal. I am having trouble with my output which is supposed to be in a certain format. Binary needs to be in the format of XXXX XXXX...
9
by: Ron Eggler | last post by:
Hi, I would like to write binary data in a file i open (ofstream) with ios::binary but it keeps failing and it gives me a segmentation fault. What I'm exactly doing: if (isBinary == true) {...
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: 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
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
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:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.