Boost logo

Boost :

From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2005-09-05 03:25:57

> -----Original Message-----
> From: boost-bounces_at_[hidden]
> [mailto:boost-bounces_at_[hidden]] On Behalf Of Matt Calabrese

Sorry Matt, I missed your immediate response, so I'll answer both now.

> > The problem is that there isn't any arbitrary precision arithmetic
> > support in the pp-lib. If there was, you could do better
> than that for
> > syntax:
> >
> > BOOST_BINARY_INT( 1100 0011 1010 )
> >
> You are under the mistaken impression that the resultant
> number would have to be a decimal literal and rely on
> Boost.Preprocessor functionality for arithmetic computations.

Yes, you are right. I was thinking about actually reading the binary digits and
*computing* the result. In other words, I was thinking about the completely
general approach rather than leveraging the compatible base property of
hexadecimal (or octal) and binary. However, the reason that I looked at it from
that perspective is because it is possible to do arbitrary-precision arithmetic
with the preprocessor (Chaos does it, for example), and I actually use binary
literals as an example in the docs. With such arbitrary-precision support, you
can read numbers in any base--hence my overlooking the obvious solution. :)

> Storing the number as a hex literal makes things much easier,
> since each nibble is just a hex digit. All you do is convert
> each nibble to hex then concatenate them all together. The
> fact that the literal is in hex, it has the downside that it
> would be more difficult to use with Boost.Preprocessor
> operations

And that doesn't really matter. Binary literals, AFAICT, are rarely useful for
expressing actual numbers so much as sets of flags.

> but then again, the template form couldn't do
> that either. Even still, if you really wanted to use it with
> Boost.Preprocessor macros, the time could be taken to make an
> implementation which results in a small decimal literal

I can already do this with Chaos, except with (theoretically) millions of
digits. :) However, I don't think it is that important (at this point) to do
that. I haven't yet encountered a situation where it would be useful.

I certainly don't mean to belittle what you've done, BTW, I'm only referring to
input to pp-lib macros in bases other than decimal. Rather, it is an expression
of frustration with and utter distaste for the pp-lib and the strictures under
which it must operate (namely, compatibility with broken preprocessors). At one
point, I tried to implement arbitrary-precision arithmetic in the pp-lib.
However, arbitrary-precision arithmetic is "somewhat complex", and I failed to
make it usuable on several popular preprocessors. In retrospect, I think
arbitrary-precision arithmetic may have been the key reason why I started the
Chaos project.

> It works exactly as I described and can be used at
> preprocessing time (though again, note that it is a hex
> literal). I do not immediately see how to implement it
> allowing the syntax you describe (where your nibbles are
> simply separated by spaces rather than using a
> Boost.Preprocessor sequence), so if you could, please
> enlighten me as I know you must be more experienced with the
> preprocessor (I love Boost.Preprocessor by the way).

I see from your other post that you solved this problem already.

> As a side note, I noticed while making this that
> BOOST_PP_SEQ_CAT fails on sequences of size 1. While
> obviously no concatenations occur with a sequence of this
> size, logically the result should just be the single element,
> so I consider this an error in Boost.Preprocessor (any
> disagreements on that?).

Well, my only excuse for this is that I'd have to check the length of the
sequence beforehand (or at least that it is less than two elements)--which takes
time. Fixed in the CVS.

> Also note that I only allowed values which are 4 binary
> digits long. This was just a design choice as I believe it
> would be confusing having nibbles in the middle that have
> under 4 digits.

Note that one of the common uses of binary literals is as packed representations
of several values. It isn't all that unusual to have a representation where the
length in bits of each part are arbitrary. If I were you, I would allow such
usage, but then you can't do a simple, direct mapping. You'd have to convert
the input to (e.g.) a sequence of bits first, and the break it up into a mapping
to hexadecimal digits. One of the advantages to doing binary literals with the
preprocessor is that you *can* do this. The template mechanism cannot
distinguish between 0001 and 01, but the preprocessor can. (Of course, it
becomes unreasonable to allow bit groups that are larger than a byte.)

> Nevermind, I figured out a way to do it myself with lots of
> macro magic. A version allowing the more simple syntax you
> originally alluded to is available here:
> Also, I changed the macro name to BOOST_BINARY_LITERAL
> Usage is as simple as:
> BOOST_BINARY_LITERAL( 101 0111 1010 0110 )
> The first nibble is allowed to be written with under 4
> explicit bits, but the remaining nibbles must use a complete
> 4 bits each. This was done to avoid confusion.

Personally, I think that you should get rid of this restriction. Allow bit
group up to eight bits (256+256 macros, I know), but where each group is not
supposed to represent a "nibble" or anything. I.e.

BINARY_LITERAL( 1 0 1 0111 10 10 011 0 )

produces the same value as above. It isn't natural, in my opinion, to have
implicit fill bits in binary literals except possibly at the beginning of the
entire thing. Allowing "1010 110" and having it mean "1010 0110" isn't just
confusing, it's an abomination.

Paul Mensonides

Boost list run by bdawes at, gregod at, cpdaniel at, john at