Why doesn't std::setbase(2) switch to binary output?
Asked Answered
E

2

10

The cppreference page on std::setbase says:

Values of base other than 8, 10, or 16 reset basefield to zero, which corresponds to decimal output and prefix-dependent input.

How come?

Is there a particular reason why only these bases are supported? It seems trivial to support at least anything up to 16 (actually, up to 36: 0-9 and then a-z) without having to make any sort of difficult choices. Specifically, 2 is a popular base, I would think there should be interest in std::setbase(2) (and a corresponding std::binary).

I can obviously print my own bits but it would have been nice for my ostream to do it.

Enrobe answered 18/4, 2016 at 19:38 Comment(2)
the nice way to print binary is en.cppreference.com/w/cpp/utility/bitset/operator_ltltgtgt2Boatswain
@Cubbi: That is nice, but it requires the code printing to the stream to be aware of the need to print in binary. I want the stream to convert to binary.Enrobe
M
8

The only sure answer is "because the standard says so".

That being said, the standard mostly formalized the pre-standard iostream implementations, many of which probably were designed just to reach feature parity with printf, which supports only decimal, octal and hexadecimal (through ad-hoc, not-really-general syntax).

Also, as it is now it wouldn't be trivial to patch the iostream API to support "many" bases, given that the base setting ends up into a bitfield, not in a separate "current base" field.

Now, the standard requires fmtflags to be of some "bitmask type" - which may even be a std::bitset, so you may find a way to shovel all those new "base" fields somehow - but is it really worth the effort (plus the risk of breaking the code that assumes that fmtflags is of an integral type) for a feature that almost nobody really cares about?

So, to sum it up: bad initial design (like the rest of iostream, actually), nontrivial fix and no real user demand for such a feature.

Martamartaban answered 28/4, 2016 at 13:4 Comment(0)
V
5

To the best of my knowledge there was no proposal to add support for binary (base 2) formatting to iostreams (see also Has there been a proposal to add std::bin to the c++ standard?). However, it is supported in C++20 std::format:

std::string s = std::format("{:b}", 42);

std::format is not widely available but you can use the {fmt} library, std::format is based on, in the meantime:

std::string s = fmt::format("{:b}", 42);

Disclaimer: I'm the author of {fmt} and C++20 std::format.

Ventilate answered 19/5, 2021 at 22:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.