Topic: Power of 2 enumerations
Author: kanze@gabi-soft.fr
Date: Wed, 10 Nov 2004 15:45:45 GMT Raw View
laurie.cheers@btinternet.com (Laurie Cheers) wrote in message
news:<c26006e0.0411090133.7c073aa6@posting.google.com>...
> dave@boost-consulting.com (David Abrahams) wrote in message
> news:<u7jow5x62.fsf@boost-consulting.com>...
> > I wonder if it's provable that _no_ such numbers collide in bases 10
> > and 8, or if it's provable that no such numbers collide in any two
> > other bases. Even in my halcyon days this was probably beyond my
> > number theory capability.
> Yes, it's provable. It's not even that complicated:
> Any power of 10 (except 0) is divisible by 5. No power of 8 is
> divisible by 5. So it's trivial to see that if we disregard 10^0, no
> sum of powers of 10 can be confused with a sum of powers of 8.
I don't follow. How does the fact that no power of 8 is divisible by 5
imply that no sum of powers of 8 is divisible by 5? The statement as it
stands is, in fact, manifestly untrue, since 8^3+8 is 520, which is
divisible by 5 (and by 10). (Of course, 520 cannot be expressed as a
sum of powers of 5, so it doesn't invalidate the original premise.)
> As for the 10^0 case, well, we can detect that. If the number is odd,
> subtract 1 and the situation reduces to the one above.
> Of course this doesn't hold for all bases. For example, 1000 in binary
> is the same as 010 in octal.
If one of the bases is a multiple of the other, the premise is obviously
false -- ALL such numbers in the larger base will collide with numbers
in the smaller base.
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: vze2hb3b@verizon.net
Date: Wed, 10 Nov 2004 17:25:19 GMT Raw View
David Abrahams <dave@boost-consulting.com> wrote:
> laurie.cheers@btinternet.com (Laurie Cheers) writes:
>
>>> I wonder if it's provable that _no_ such numbers collide in bases 10
>>> and 8, or if it's provable that no such numbers collide in any two
>>> other bases. Even in my halcyon days this was probably beyond my
>>> number theory capability.
>>
>> Yes, it's provable. It's not even that complicated:
>> Any power of 10 (except 0) is divisible by 5. No power of 8 is divisible by 5.
>> So it's trivial to see that if we disregard 10^0, no sum of powers of 10
>> can be confused with a sum of powers of 8.
>>
>> As for the 10^0 case, well, we can detect that. If the number is odd,
>> subtract 1 and the situation reduces to the one above.
>>
>>
>> Of course this doesn't hold for all bases. For example, 1000 in binary is the
>> same as 010 in octal.
>
> When someone really smart shows it, it always looks so simple ;-)
>
Unfortunately the trivial part of the "proof" above is the one about 10^0 and
the non-trivial is the one that is claimed trivial. For instance if we consider
2 and 10 (instead of 8 and 10) the same argument about divisibility of powers of
2 and 10 by 5 applies, yet 10 = 8 + 2 = 2^3 + 2^1.
The actual real proof goes something like this:
As mentioned earlier we can consider only even numbers. Let N be a number that
can be represented as a sum of powers of 10 and a sum of powers of 8 and let
k be the smallest power of 10 and l be the smallest power of 8 in the corresponding
representations:
N = 10^k*(10*K + 1) = 2^k*5^k(10*K + 1);
N = 8^l(8*L + 1) = 2^(3*l)(8*L + 1).
Note that 5^k(10*K + 1) and 8*L + 1 are odd numbers, so k must be
equal to 3*l, since otherwise we can cancel all powers of 2 in one
representation of N and not in the other and get the contradiction
in the result being both even and odd...
So k = 3*l and we have
(*) 5^k(10*K + 1) = 8*L + 1
Now 10*K + 1 is an odd number and any power of 5 times an odd number
has 5 as the last digit in its decimal representation. So 8*L + 1 must
have 5 as the last digit in its decimal representation, or 8*L must
have 4 as the last digit. This means that L = 3 + 5*S , so
8*L + 1 = 25 + 40*S. But the highest power of 5 in 25 + 40*S is 5^2
(if S is divisible by 5), so from (*) k must be <= 2. On the other
hand k = 3*l which means that k = l = 0. But this contradicts our
initial assumption that N does not contain 10^0 and 8^0 in its
representation.
Hope I did not miss anything.
--
Aleksandr Morgulis
aleksandr.morgulis@verizon.net
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jdennett@acm.org (James Dennett)
Date: Wed, 10 Nov 2004 18:18:04 GMT Raw View
David Abrahams wrote:
> laurie.cheers@btinternet.com (Laurie Cheers) writes:
>
>
>>>I wonder if it's provable that _no_ such numbers collide in bases 10
>>>and 8, or if it's provable that no such numbers collide in any two
>>>other bases. Even in my halcyon days this was probably beyond my
>>>number theory capability.
>>
>>Yes, it's provable. It's not even that complicated:
>>Any power of 10 (except 0) is divisible by 5.
True.
>> No power of 8 is divisible by 5.
True.
>>So it's trivial to see that if we disregard 10^0, no sum of powers of 10
>>can be confused with a sum of powers of 8.
Sadly that doesn't follow. You've given reason enough to know
that no sum of powers of 10 can be confused with a (single)
power of 8.
The gap is that the sum of two numbers which aren't divisible
by 5 can itself be divisible by 5. Indeed, it will happen,
for example:
8 + 8*8 + 8*8*8 + 8*8*8*8 = 8 + 64 + 512 + 4096 = 4680
(Give me an infinite number of numbers which aren't divisible
by n, and I'll guarantee that there are infinitely many finite
sums among them are divisible by n.)
>>As for the 10^0 case, well, we can detect that. If the number is odd,
>>subtract 1 and the situation reduces to the one above.
>>
>>
>>Of course this doesn't hold for all bases. For example, 1000 in binary is the
>>same as 010 in octal.
>
>
> When someone really smart shows it, it always looks so simple ;-)
Too simple this time?
-- James
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: laurie.cheers@btinternet.com (Laurie Cheers)
Date: Wed, 10 Nov 2004 18:18:27 GMT Raw View
dave@boost-consulting.com (David Abrahams) wrote in message news:<usm7itzza.fsf@boost-consulting.com>...
> laurie.cheers@btinternet.com (Laurie Cheers) writes:
> >> I wonder if it's provable that _no_ such numbers collide in bases 10
> >> and 8, or if it's provable that no such numbers collide in any two
> >> other bases. Even in my halcyon days this was probably beyond my
> >> number theory capability.
> >
> > Yes, it's provable. It's not even that complicated:
> > Any power of 10 (except 0) is divisible by 5. No power of 8 is divisible by
> > 5. So it's trivial to see that if we disregard 10^0, no sum of powers of 10
> > can be confused with a sum of powers of 8.
Oops. Unfortunately that's not quite true.
For example, 8^3 + 8^1 = 512 + 8 = 520, which is divisible by 5.
It sounded good though, didn't it? :)
--
Laurie Cheers
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 10 Nov 2004 18:19:15 GMT Raw View
Laurie Cheers wrote:
> Yes, it's provable. It's not even that complicated:
> Any power of 10 (except 0) is divisible by 5.
> No power of 8 is divisible by 5.
> So it's trivial to see that if we disregard 10^0,
> no sum of powers of 10 can be confused with a sum
> of powers of 8.
I don't think it's as trivial as you think. We want
to find sequences (a, b, ..., n) and (A, B, ..., N)
such that 0 < a < b < ... < n and 0 < A < B < ... < N
and 8^a + 8^b + ... + 8^n = 10^A + 10^B + ... + 10^N.
Then 8^a(1 + 8^(b-a) + ... + 8^(n-A) =
10^A(1 + 10^(B-A) + ... + 10^(N-A))
Now, if we set A = 3a, then we could find a solution
if there existed a set of powers of 8 (including 1)
which summed to a power of 125. You probably can't
find one, but I don't think the proof is just by
observation.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: wade@stoner.com (Bill Wade)
Date: Wed, 10 Nov 2004 18:19:25 GMT Raw View
laurie.cheers@btinternet.com (Laurie Cheers) wrote in message news:<c26006e0.0411090133.7c073aa6@posting.google.com>...
> > I wonder if it's provable that _no_ such numbers collide in bases 10
> > and 8, or if it's provable that no such numbers collide in any two
> > other bases. Even in my halcyon days this was probably beyond my
> > number theory capability.
>
> Yes, it's provable. It's not even that complicated:
> Any power of 10 (except 0) is divisible by 5. No power of 8 is divisible by 5.
> So it's trivial to see that if we disregard 10^0, no sum of powers of 10
> can be confused with a sum of powers of 8.
I don't see how this is a complete proof. The fact that no power of
eight is divisible by 5 says nothing about whether sums of powers of 8
are divisible by five (8^3+8 is divisible by 5).
If I replace every occurance of "8" with "2" in your proof, can I
prove that "no sum of powers of 10 can be confused with a sum of
powers of 2"?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Thu, 11 Nov 2004 01:13:02 GMT Raw View
In article <d6652001.0411100240.4ed211f7@posting.google.com>,
kanze@gabi-soft.fr writes
>> Any power of 10 (except 0) is divisible by 5. No power of 8 is
>> divisible by 5. So it's trivial to see that if we disregard 10^0, no
>> sum of powers of 10 can be confused with a sum of powers of 8.
>
>I don't follow. How does the fact that no power of 8 is divisible by 5
>imply that no sum of powers of 8 is divisible by 5? The statement as it
>stands is, in fact, manifestly untrue, since 8^3+8 is 520, which is
>divisible by 5 (and by 10). (Of course, 520 cannot be expressed as a
>sum of powers of 5, so it doesn't invalidate the original premise.)
Indeed, and I suspect that the assertion is false though I do not have
the time to find a counter example. However consider using base 5 and
base 4 (where the argument above would be just as applicable)
11 base 4 == 10 base five
And while that assertion is true for all consecutive bases this is also
true:
10 base 9 = 111 base 8
The existence of such simple counter examples for other bases leads be
to expect that they also exist for base 10 and base 8.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Thu, 11 Nov 2004 01:13:27 GMT Raw View
kanze@gabi-soft.fr writes:
> laurie.cheers@btinternet.com (Laurie Cheers) wrote in message
> news:<c26006e0.0411090133.7c073aa6@posting.google.com>...
>> dave@boost-consulting.com (David Abrahams) wrote in message
>> news:<u7jow5x62.fsf@boost-consulting.com>...
>
>> > I wonder if it's provable that _no_ such numbers collide in bases 10
>> > and 8, or if it's provable that no such numbers collide in any two
>> > other bases. Even in my halcyon days this was probably beyond my
>> > number theory capability.
>
>> Yes, it's provable. It's not even that complicated:
>
>> Any power of 10 (except 0) is divisible by 5. No power of 8 is
>> divisible by 5. So it's trivial to see that if we disregard 10^0, no
>> sum of powers of 10 can be confused with a sum of powers of 8.
>
> I don't follow. How does the fact that no power of 8 is divisible by 5
> imply that no sum of powers of 8 is divisible by 5? The statement as it
> stands is, in fact, manifestly untrue, since 8^3+8 is 520, which is
> divisible by 5 (and by 10). (Of course, 520 cannot be expressed as a
> sum of powers of 5, so it doesn't invalidate the original premise.)
I guess maybe that's why the solution seemed so simple.
I'm pretty sure that divisibility is the wrong thing to be looking
at, at least in such straightforward terms, because the 1s digit gets
involved.
8^1 + 8^0 = 9
What can you say about that w.r.t. divisibility? Not much.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kanze@gabi-soft.fr
Date: Fri, 12 Nov 2004 20:07:30 GMT Raw View
vze2hb3b@verizon.net wrote in message news:<CVfkd.787$w.258@trnddc02>...
> David Abrahams <dave@boost-consulting.com> wrote:
> > laurie.cheers@btinternet.com (Laurie Cheers) writes:
> >>> I wonder if it's provable that _no_ such numbers collide in bases
> >>> 10 and 8, or if it's provable that no such numbers collide in any
> >>> two other bases. Even in my halcyon days this was probably beyond
> >>> my number theory capability.
> >> Yes, it's provable. It's not even that complicated:
> >> Any power of 10 (except 0) is divisible by 5. No power of 8 is
> >> divisible by 5. So it's trivial to see that if we disregard 10^0,
> >> no sum of powers of 10 can be confused with a sum of powers of 8.
> >> As for the 10^0 case, well, we can detect that. If the number is
> >> odd, subtract 1 and the situation reduces to the one above.
> >> Of course this doesn't hold for all bases. For example, 1000 in
> >> binary is the same as 010 in octal.
> > When someone really smart shows it, it always looks so simple ;-)
> Unfortunately the trivial part of the "proof" above is the one about
> 10^0 and the non-trivial is the one that is claimed trivial. For
> instance if we consider 2 and 10 (instead of 8 and 10) the same
> argument about divisibility of powers of 2 and 10 by 5 applies, yet 10
> = 8 + 2 = 2^3 + 2^1.
> The actual real proof goes something like this:
> As mentioned earlier we can consider only even numbers. Let N be a
> number that can be represented as a sum of powers of 10 and a sum of
> powers of 8 and let k be the smallest power of 10 and l be the
> smallest power of 8 in the corresponding representations:
> N = 10^k*(10*K + 1) = 2^k*5^k(10*K + 1);
> N = 8^l(8*L + 1) = 2^(3*l)(8*L + 1).
> Note that 5^k(10*K + 1) and 8*L + 1 are odd numbers, so k must be
> equal to 3*l, since otherwise we can cancel all powers of 2 in one
> representation of N and not in the other and get the contradiction in
> the result being both even and odd...
> So k = 3*l and we have
> (*) 5^k(10*K + 1) = 8*L + 1
> Now 10*K + 1 is an odd number and any power of 5 times an odd number
> has 5 as the last digit in its decimal representation. So 8*L + 1 must
> have 5 as the last digit in its decimal representation, or 8*L must
> have 4 as the last digit. This means that L = 3 + 5*S , so 8*L + 1 =
> 25 + 40*S.
Fine so far (as far as I can see), but...
> But the highest power of 5 in 25 + 40*S is 5^2 (if S is
> divisible by 5), so from (*) k must be <= 2.
How can you say this? If S=15, for example, 25 + 40*S = 625, 5^4. In
fact, you can find an S that works for any even power of 5 (S=1950 gives
5^6, S = 48825 gives 5^8, etc.).
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: vze2hb3b@verizon.net
Date: Sat, 13 Nov 2004 05:30:05 GMT Raw View
kanze@gabi-soft.fr wrote:
> vze2hb3b@verizon.net wrote in message news:<CVfkd.787$w.258@trnddc02>...
>> David Abrahams <dave@boost-consulting.com> wrote:
>> > laurie.cheers@btinternet.com (Laurie Cheers) writes:
>
>> >>> I wonder if it's provable that _no_ such numbers collide in bases
>> >>> 10 and 8, or if it's provable that no such numbers collide in any
>> >>> two other bases. Even in my halcyon days this was probably beyond
>> >>> my number theory capability.
>
>> >> Yes, it's provable. It's not even that complicated:
>> >> Any power of 10 (except 0) is divisible by 5. No power of 8 is
>> >> divisible by 5. So it's trivial to see that if we disregard 10^0,
>> >> no sum of powers of 10 can be confused with a sum of powers of 8.
>
>> >> As for the 10^0 case, well, we can detect that. If the number is
>> >> odd, subtract 1 and the situation reduces to the one above.
>
>> >> Of course this doesn't hold for all bases. For example, 1000 in
>> >> binary is the same as 010 in octal.
>
>> > When someone really smart shows it, it always looks so simple ;-)
>
>> Unfortunately the trivial part of the "proof" above is the one about
>> 10^0 and the non-trivial is the one that is claimed trivial. For
>> instance if we consider 2 and 10 (instead of 8 and 10) the same
>> argument about divisibility of powers of 2 and 10 by 5 applies, yet 10
>> = 8 + 2 = 2^3 + 2^1.
>
>> The actual real proof goes something like this:
>
>> As mentioned earlier we can consider only even numbers. Let N be a
>> number that can be represented as a sum of powers of 10 and a sum of
>> powers of 8 and let k be the smallest power of 10 and l be the
>> smallest power of 8 in the corresponding representations:
>
>> N = 10^k*(10*K + 1) = 2^k*5^k(10*K + 1);
>> N = 8^l(8*L + 1) = 2^(3*l)(8*L + 1).
>
>> Note that 5^k(10*K + 1) and 8*L + 1 are odd numbers, so k must be
>> equal to 3*l, since otherwise we can cancel all powers of 2 in one
>> representation of N and not in the other and get the contradiction in
>> the result being both even and odd...
>
>> So k = 3*l and we have
>
>> (*) 5^k(10*K + 1) = 8*L + 1
>
>> Now 10*K + 1 is an odd number and any power of 5 times an odd number
>> has 5 as the last digit in its decimal representation. So 8*L + 1 must
>> have 5 as the last digit in its decimal representation, or 8*L must
>> have 4 as the last digit. This means that L = 3 + 5*S , so 8*L + 1 =
>> 25 + 40*S.
>
> Fine so far (as far as I can see), but...
>
>> But the highest power of 5 in 25 + 40*S is 5^2 (if S is
>> divisible by 5), so from (*) k must be <= 2.
>
> How can you say this? If S=15, for example, 25 + 40*S = 625, 5^4. In
> fact, you can find an S that works for any even power of 5 (S=1950 gives
> 5^6, S = 48825 gives 5^8, etc.).
>
Thanks, James. My mistake. After looking at it more carefully, the problem
does not seem simple at all. Somehow the proof (if one exists) should use
the fact that in (*) the right side and the expression in parentheses on
the left side are also sums of powers of 8 and 10 correspondingly. Maybe
some kind of induction can be carried out, but I can not see it yet.
> --
> James Kanze GABI Software http://www.gabi-soft.fr
> Conseils en informatique orient?e objet/
> Beratung in objektorientierter Datenverarbeitung
> 9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
>
--
Aleksandr Morgulis
aleksandr.morgulis@verizon.net
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: user@example.net (Mark)
Date: Fri, 29 Oct 2004 01:50:04 GMT Raw View
Just curious,
Is there any proposal to add the above enumerations
to C++ in future?
For example, instead of
enum
{
FEATURE1 = 1,
FEATURE2 = 2,
FEATURE3 = 4
};
we could have
typedef binary enum
{
FEATURE1,
FEATURE2,
FEATURE3
}feature_t;
void foo( feature_t f )
{
if( f & FEATURE1 )
{
}
}
int main()
{
foo( FEATURE1 | FEATURE2 );
}
so the numbers are assigned automatically and there is
no casting required to OR the values in main, ie the
typing is retained.
Cheers,
Mark.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: redterminator@fap.net ("assaarpa")
Date: Fri, 29 Oct 2004 17:20:57 GMT Raw View
> Is there any proposal to add the above enumerations
> to C++ in future?
I hope not, what you are proposing is something that can easily be done
using existing language constructs.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: technews@kangaroologic.com ("Jonathan Turkanis")
Date: Fri, 29 Oct 2004 18:28:47 GMT Raw View
"Mark" <user@example.net> wrote in message
news:41815068$0$33591$ed2619ec@ptn-nntp-reader02.plus.net...
> Just curious,
> Is there any proposal to add the above enumerations
> to C++ in future?
>
> For example, instead of
>
> enum
> {
> FEATURE1 = 1,
> FEATURE2 = 2,
> FEATURE3 = 4
> };
>
> we could have
>
>
> typedef binary enum
> {
> FEATURE1,
> FEATURE2,
> FEATURE3
>
> }feature_t;
But this is easy to do already:
enum features
{
FEATURE1 = 1,
FEATURE2 = FEATURE1 << 1,
FEATURE3 = FEATURE2 << 1
};
It think there's much more urgent need for this:
fibonacci enum features
{
FEATURE1,
FEATURE2,
FEATURE3,
FEATURE4
};
To replace the common but error-prone idiom:
enum features
{
FEATURE1 = 1,
FEATURE2 = 1,
FEATURE3 = FEATURE1 + FEATURE2,
FEATURE4 = FEATURE2 + FEATURE3,
...
};
;-)
> Cheers,
> Mark.
Jonathan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: tannhauser86549spam@free.fr (=?ISO-8859-1?Q?Falk_Tannh=E4user?=)
Date: Fri, 29 Oct 2004 22:04:22 GMT Raw View
Jonathan Turkanis wrote:
> It think there's much more urgent need for this:
>
> fibonacci enum features
> {
> FEATURE1,
> FEATURE2,
> FEATURE3,
> FEATURE4
> };
>
> To replace the common but error-prone idiom:
>
> enum features
> {
> FEATURE1 = 1,
> FEATURE2 = 1,
> FEATURE3 = FEATURE1 + FEATURE2,
> FEATURE4 = FEATURE2 + FEATURE3,
> ...
> };
Hey, that can already be done using existing language feature, too!
template<unsigned N> struct fibonacci
{ enum { feature = fibonacci<N-1>::feature + fibonacci<N-2>::feature }; };
template<> struct fibonacci<0> { enum { feature = 0 }; };
template<> struct fibonacci<1> { enum { feature = 1 }; };
>
> ;-)
ditto...
Falk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: user@example.net (Mark)
Date: Sun, 31 Oct 2004 08:11:54 GMT Raw View
assaarpa wrote:
>>Is there any proposal to add the above enumerations
>>to C++ in future?
>
>
> I hope not, what you are proposing is something that can easily be done
> using existing language constructs.
The problem is it's not done very well at all with
current language constructs is it?
If you want to use this idiom, you have to make these
types integers or unsigned integers, so you loose the
type safety.
The other alternative is to use ugly casts to convert
the result back into your type. Neither is a great
solution!
So is there a more elegant solution I don't know about?
Cheers,
Mark.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Sun, 31 Oct 2004 19:33:39 GMT Raw View
There are bit fields for that.
struct flags {
bool field1: 1;
bool field2: 1;
bool field3: 1;
};
That's the proper way to do bit fields. It's underutilized,
but works fine.
Unfortunately, bitfields and arrays don't interact well.
You can't create a packed array of bits:
struct bitmap {
bool pixel: 1 [640*480];
};
Logically, that should work, but it doesn't. Does anyone
know why?
John Nagle
Mark wrote:
> assaarpa wrote:
>
>>> Is there any proposal to add the above enumerations
>>> to C++ in future?
>>
>>
>>
>> I hope not, what you are proposing is something that can easily be
>> done using existing language constructs.
>
>
> The problem is it's not done very well at all with
> current language constructs is it?
>
> If you want to use this idiom, you have to make these
> types integers or unsigned integers, so you loose the
> type safety.
>
> The other alternative is to use ugly casts to convert
> the result back into your type. Neither is a great
> solution!
>
> So is there a more elegant solution I don't know about?
>
> Cheers,
> Mark.
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Mon, 1 Nov 2004 02:52:13 GMT Raw View
In article <eMahd.37057$QJ3.13078@newssvr21.news.prodigy.com>, John
Nagle <nagle@animats.com> writes
>Unfortunately, bitfields and arrays don't interact well.
>You can't create a packed array of bits:
>
> struct bitmap {
> bool pixel: 1 [640*480];
> };
>
>Logically, that should work, but it doesn't. Does anyone
>know why?
I think a bitset meets that need.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: NONONE@nowhere.com ("Jeff Flinn")
Date: Mon, 1 Nov 2004 10:03:33 GMT Raw View
"Mark" <user@example.net> wrote in message
news:41815068$0$33591$ed2619ec@ptn-nntp-reader02.plus.net...
> Just curious,
> Is there any proposal to add the above enumerations
> to C++ in future?
>
> For example, instead of
>
> enum
> {
> FEATURE1 = 1,
> FEATURE2 = 2,
> FEATURE3 = 4
> };
>
> we could have
>
>
> typedef binary enum
> {
> FEATURE1,
> FEATURE2,
> FEATURE3
>
> }feature_t;
But we already have:
typedef std::bitset<3> feature_t;
>
>
> void foo( feature_t f )
> {
> if( f & FEATURE1 )
if( f[0] )
> {
> }
> }
>
> int main()
> {
> foo( FEATURE1 | FEATURE2 );
foo( feature_t("011") );
> }
>
> so the numbers are assigned automatically and there is
> no casting required to OR the values in main, ie the
> typing is retained.
And if you want to emulate your FEATUREn instances:
const feature_t FEATURE1 = feature_t("001");
const feature_t FEATURE2 = feature_t("010");
const feature_t FEATURE3 = feature_t("100");
-----------------
Jeff Flinn
Applied Dynamics, International
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: bekkah@web.de (Helium)
Date: Mon, 1 Nov 2004 19:55:05 GMT Raw View
> assaarpa wrote:
> >>Is there any proposal to add the above enumerations
> >>to C++ in future?
> >
> >
> > I hope not, what you are proposing is something that can easily be done
> > using existing language constructs.
>
> The problem is it's not done very well at all with
> current language constructs is it?
>
> If you want to use this idiom, you have to make these
> types integers or unsigned integers, so you loose the
> type safety.
>
> The other alternative is to use ugly casts to convert
> the result back into your type. Neither is a great
> solution!
>
> So is there a more elegant solution I don't know about?
Well, what's wrong with the suggestedone?
enum Foo {
flag1 = 1,
flag2 = 2,
flag3 = 4,
flag4 = 8
};
Foo operator | (Foo lhs, Foo rhs)
{
return static_cast<Foo>(lhs | rhs);
}
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 1 Nov 2004 19:54:50 GMT Raw View
NONONE@nowhere.com ("Jeff Flinn") writes:
> And if you want to emulate your FEATUREn instances:
>
> const feature_t FEATURE1 = feature_t("001");
> const feature_t FEATURE2 = feature_t("010");
> const feature_t FEATURE3 = feature_t("100");
You can even write a simple template that makes these into
compile-time constants:
const feature_t FEATURE1 = binary<001>::value;
const feature_t FEATURE2 = binary<010>::value;
const feature_t FEATURE3 = binary<100>::value;
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Mon, 1 Nov 2004 19:54:49 GMT Raw View
Francis Glassborow wrote:
> In article <eMahd.37057$QJ3.13078@newssvr21.news.prodigy.com>, John
> Nagle <nagle@animats.com> writes
>
>> Unfortunately, bitfields and arrays don't interact well.
>> You can't create a packed array of bits:
>>
>> struct bitmap {
>> bool pixel: 1 [640*480];
>> };
>>
>> Logically, that should work, but it doesn't. Does anyone
>> know why?
>
>
> I think a bitset meets that need.
It helps. But you can't declare a small field in
the middle of a record as a bitset. Bitsets are
arrays of longs, and are word aligned. Bitsets are not helpful
when you have to match some existing data format for
network or file purposes, which is what bitfields are
usually used for.
John Nagle
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: v.Abazarov@comAcast.net (Victor Bazarov)
Date: Tue, 2 Nov 2004 05:43:39 GMT Raw View
David Abrahams wrote:
> NONONE@nowhere.com ("Jeff Flinn") writes:
>
>
>>And if you want to emulate your FEATUREn instances:
>>
>>const feature_t FEATURE1 = feature_t("001");
>>const feature_t FEATURE2 = feature_t("010");
>>const feature_t FEATURE3 = feature_t("100");
>
>
> You can even write a simple template that makes these into
> compile-time constants:
>
> const feature_t FEATURE1 = binary<001>::value;
> const feature_t FEATURE2 = binary<010>::value;
> const feature_t FEATURE3 = binary<100>::value;
>
Tricky because 010 and 10 are not the same in C++. You can control
the behaviour of the class when strings are used so "010" and "10"
would mean the same, but you cannot control the behaviour of integer
literals. It would really be nice if C++ got binary literals (some
compilers had or have them), in the form of <binary_digits>b or
something of that nature. Then you can have 010b or 10b which will
be the same.
V
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dsp@bdal.de (=?ISO-8859-1?Q?=22Daniel_Kr=FCgler_=28ne_Spangenberg=29=22?=)
Date: Tue, 2 Nov 2004 16:02:40 GMT Raw View
Hekllo Helium,
Helium schrieb:
>Well, what's wrong with the suggestedone?
>
>enum Foo {
> flag1 = 1,
> flag2 = 2,
> flag3 = 4,
> flag4 = 8
>};
>
>Foo operator | (Foo lhs, Foo rhs)
>{
> return static_cast<Foo>(lhs | rhs);
>}
>
>
That it enforces a recursive function call? ;-))
I think, you meant
Foo operator|(Foo lhs, Foo rhs)
{
return static_cast<Foo>(static_cast<unsigned>(lhs) |
static_cast<unsigned>(rhs));
}
don't you?
(It is a shame, that it currently is not possible to portably deduce the
underlying integer
type of an enumeration type, but fortunatly there are attempts to fix
this deficiency, e.g.
by Sutter et al.)
Greetings from Bremen,
Daniel
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kanze@gabi-soft.fr
Date: Wed, 3 Nov 2004 19:28:33 GMT Raw View
bekkah@web.de (Helium) wrote in message
news:<194c1211.0411011000.726472cd@posting.google.com>...
> Well, what's wrong with the suggestedone?
> enum Foo {
> flag1 = 1,
> flag2 = 2,
> flag3 = 4,
> flag4 = 8
> };
> Foo operator | (Foo lhs, Foo rhs)
> {
> return static_cast<Foo>(lhs | rhs);
> }
Infinite recursion.
I get bitten by it almost every time. It's so easy to forget to cast
the parameters to unsigned or whatever first. And it's a potential
maintenance problem -- adding enum values can change the underlying type
of the enum, and make the original cast illegal.
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: rmaddox@isicns.com (Randy Maddox)
Date: Thu, 4 Nov 2004 04:53:26 GMT Raw View
bekkah@web.de (Helium) wrote in message news:<194c1211.0411011000.726472cd@posting.google.com>...
> > assaarpa wrote:
> >
[snip]
> > So is there a more elegant solution I don't know about?
>
> Well, what's wrong with the suggestedone?
>
> enum Foo {
> flag1 = 1,
> flag2 = 2,
> flag3 = 4,
> flag4 = 8
> };
>
> Foo operator | (Foo lhs, Foo rhs)
> {
> return static_cast<Foo>(lhs | rhs);
> }
>
You mean other than 5.2.9/7, which says:
A value of integral or enumeration type can be explicitly converted to
an enumeration type. The value is unchanged if the original value is
within the range of the enumeration values (7.2). Otherwise, the
resulting enumeration value is unspecified.
So that, for example, Foo flagUnspecified = flag3 | flag4 yields a
value, 12, that is not in the range of Foo enumeration values.
Randy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: brangdon@cix.co.uk (Dave Harris)
Date: Thu, 4 Nov 2004 04:54:56 GMT Raw View
user@example.net (Mark) wrote (abridged):
> So is there a more elegant solution I don't know about?
I like to put enums into their own namespace. Given that, it seems to me
it ought to be possible to have a library solution whose use would
look like:
#include "BitEnum.h"
namespace Flags {
using namespace BitEnum;
enum Type { Feature1=0x01, Feature2=0x02, Feature3=0x04 };
}
Flags::Type f = Flags::Feature1 | Flags::Feature2;
The using directive is what tells the compiler we want bit-wise operations
rather than ordinal operations like operator++() (for which there would be
another namespace).
The header should be something like:
namespace BitEnum {
typedef unsigned long Base;
template <typename E>
E operator|( E left, E right ) {
return E( left | static_cast<Base>( right ) );
}
template <typename E>
E operator&( E left, E right ) {
return E( left & static_cast<Base>( right ) );
}
template <typename E>
E operator~( E e ) {
return E( ~static_cast<Base>( e ) );
}
// Other operators and handy functions...
}
However, this doesn't compile with:
http://www.comeaucomputing.com/tryitout/
I also tried using a struct instead of a namespace, using the "friend"
trick, using explicit instantiation and using the curiously recurring
template pattern. In no case could I get Comeau to use the definition of
operator|() I wanted. Assuming Comeau is correct, I guess I don't
understand argument dependant look-up as well as I should. Maybe someone
cleverer than me can get it to work. (Or confirm that Comeau is wrong.)
-- Dave Harris, Nottingham, UK
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Thu, 4 Nov 2004 22:34:08 GMT Raw View
In article <8c8b368d.0411020548.65de2777@posting.google.com>, Randy
Maddox <rmaddox@isicns.com> writes
>You mean other than 5.2.9/7, which says:
>
>A value of integral or enumeration type can be explicitly converted to
>an enumeration type. The value is unchanged if the original value is
>within the range of the enumeration values (7.2). Otherwise, the
>resulting enumeration value is unspecified.
>
>So that, for example, Foo flagUnspecified = flag3 | flag4 yields a
>value, 12, that is not in the range of Foo enumeration values.
Read 7.2 paragraph 6 which was drafted specifically to ensure that ORing
all the enumerators resulted in a value within the enumeration range.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: j_richter@gmx.de (Joerg Richter)
Date: Fri, 5 Nov 2004 06:17:18 GMT Raw View
brangdon@cix.co.uk (Dave Harris) wrote:
> #include "BitEnum.h"
>
> namespace Flags {
> using namespace BitEnum;
> enum Type { Feature1=0x01, Feature2=0x02, Feature3=0x04 };
> }
>
> Flags::Type f = Flags::Feature1 | Flags::Feature2;
>
> ...
>
> I also tried using a struct instead of a namespace, using the "friend"
> trick, using explicit instantiation and using the curiously recurring
> template pattern. In no case could I get Comeau to use the definition of
> operator|() I wanted. Assuming Comeau is correct, I guess I don't
> understand argument dependant look-up as well as I should. Maybe someone
> cleverer than me can get it to work. (Or confirm that Comeau is wrong.)
Some time ago I had the same problem.
I found my answer in "C++ Templates": using directives are ignored
when doing ADL. :(
Joerg
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: falk.tannhauser@crf.canon.fr (=?ISO-8859-1?Q?Falk_Tannh=E4user?=)
Date: Fri, 5 Nov 2004 07:00:06 GMT Raw View
X-Replace-Address:yes
kanze@gabi-soft.fr wrote:
> bekkah@web.de (Helium) wrote in message
>=20
>>Well, what's wrong with the suggestedone?
>>enum Foo {
>> flag1 =3D 1,
>> flag2 =3D 2,
>> flag3 =3D 4,
>> flag4 =3D 8
>>};
>=20
>>Foo operator | (Foo lhs, Foo rhs)
>>{
>> return static_cast<Foo>(lhs | rhs);
>>}
>=20
> Infinite recursion.
>=20
> I get bitten by it almost every time. It's so easy to forget to cast
> the parameters to unsigned or whatever first. And it's a potential
> maintenance problem -- adding enum values can change the underlying typ=
e
> of the enum, and make the original cast illegal.
How about
inline Foo operator | (Foo lhs, Foo rhs)
{
return static_cast<Foo>(+lhs | +rhs);
}
to force the integral promotion to the Right Type (=A7 4.5/2, =A7 5.3.1/6=
)?
Falk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ms@ms.net (MS)
Date: Fri, 5 Nov 2004 07:00:12 GMT Raw View
>
> However, this doesn't compile with:
> http://www.comeaucomputing.com/tryitout/
>
> I also tried using a struct instead of a namespace, using the "friend"
> trick, using explicit instantiation and using the curiously recurring
> template pattern. In no case could I get Comeau to use the definition of
> operator|() I wanted. Assuming Comeau is correct, I guess I don't
> understand argument dependant look-up as well as I should. Maybe someone
> cleverer than me can get it to work. (Or confirm that Comeau is wrong.)
FWIW your original code compiles fine with vc7.1 and by changing
namespace Flags {
using namespace BitEnum;
enum Type { Feature1=0x01, Feature2=0x02, Feature3=0x04 };
}
to
namespace Flags {
using namespace BitEnum;
using BitEnum::operator|;
enum Type { Feature1=0x01, Feature2=0x02, Feature3=0x04 };
}
it compiles with Comeau. I'm hoping Comeau is incorrect as it looks
like a very nice solution.
cheers
martin
-- email at mslater dot hellinc dot net
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jdennett@acm.org (James Dennett)
Date: Sat, 6 Nov 2004 21:45:43 GMT Raw View
Victor Bazarov wrote:
> David Abrahams wrote:
>
>> NONONE@nowhere.com ("Jeff Flinn") writes:
>>
>>
>>> And if you want to emulate your FEATUREn instances:
>>>
>>> const feature_t FEATURE1 = feature_t("001");
>>> const feature_t FEATURE2 = feature_t("010");
>>> const feature_t FEATURE3 = feature_t("100");
>>
>>
>>
>> You can even write a simple template that makes these into
>> compile-time constants:
>>
>> const feature_t FEATURE1 = binary<001>::value;
>> const feature_t FEATURE2 = binary<010>::value;
>> const feature_t FEATURE3 = binary<100>::value;
>>
>
> Tricky because 010 and 10 are not the same in C++.
But with our freedom to write (over-)complicated templates,
that can be handled, by making a template which treats
8^n the same as 10^n, where I use ^ as power, not xor.
(There's no ambiguity except in the case 8^0==10^0==1,
where the ambiguity is harmless anyway.)
Of course this would then allow
feature_t const FEATURE4 = binary<64>::value;
as an ugly synonym for
feature_t const FEATURE4 = binary<0100>::value;
but then "nobody would do that, would they?".
-- James
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: v.Abazarov@comAcast.net ("Victor Bazarov")
Date: Sun, 7 Nov 2004 19:04:58 GMT Raw View
"James Dennett" <jdennett@acm.org> wrote...
> Victor Bazarov wrote:
>
>> David Abrahams wrote:
>>
>>> NONONE@nowhere.com ("Jeff Flinn") writes:
>>>
>>>
>>>> And if you want to emulate your FEATUREn instances:
>>>>
>>>> const feature_t FEATURE1 = feature_t("001");
>>>> const feature_t FEATURE2 = feature_t("010");
>>>> const feature_t FEATURE3 = feature_t("100");
>>>
>>>
>>>
>>> You can even write a simple template that makes these into
>>> compile-time constants:
>>>
>>> const feature_t FEATURE1 = binary<001>::value;
>>> const feature_t FEATURE2 = binary<010>::value;
>>> const feature_t FEATURE3 = binary<100>::value;
>>>
>>
>> Tricky because 010 and 10 are not the same in C++.
>
> But with our freedom to write (over-)complicated templates,
> that can be handled, by making a template which treats
> 8^n the same as 10^n, where I use ^ as power, not xor.
> (There's no ambiguity except in the case 8^0==10^0==1,
> where the ambiguity is harmless anyway.)
>
> Of course this would then allow
>
> feature_t const FEATURE4 = binary<64>::value;
>
> as an ugly synonym for
>
> feature_t const FEATURE4 = binary<0100>::value;
>
> but then "nobody would do that, would they?".
It's not the matter of 64 being the same as 0100. It's the matter
of 100 not being the same as 0100. It simple _cannot_ be resolved
using any complexity in templates. Period.
V
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jdennett@acm.org (James Dennett)
Date: Mon, 8 Nov 2004 02:03:20 GMT Raw View
Victor Bazarov wrote:
> "James Dennett" <jdennett@acm.org> wrote...
>
>>Victor Bazarov wrote:
>>
>>
>>>David Abrahams wrote:
>>>
>>>
>>>>NONONE@nowhere.com ("Jeff Flinn") writes:
>>>>
>>>>
>>>>
>>>>>And if you want to emulate your FEATUREn instances:
>>>>>
>>>>>const feature_t FEATURE1 = feature_t("001");
>>>>>const feature_t FEATURE2 = feature_t("010");
>>>>>const feature_t FEATURE3 = feature_t("100");
>>>>
>>>>
>>>>
>>>>You can even write a simple template that makes these into
>>>>compile-time constants:
>>>>
>>>>const feature_t FEATURE1 = binary<001>::value;
>>>>const feature_t FEATURE2 = binary<010>::value;
>>>>const feature_t FEATURE3 = binary<100>::value;
>>>>
>>>
>>>Tricky because 010 and 10 are not the same in C++.
>>
>>But with our freedom to write (over-)complicated templates,
>>that can be handled, by making a template which treats
>>8^n the same as 10^n, where I use ^ as power, not xor.
>>(There's no ambiguity except in the case 8^0==10^0==1,
>>where the ambiguity is harmless anyway.)
>>
>>Of course this would then allow
>>
>>feature_t const FEATURE4 = binary<64>::value;
>>
>>as an ugly synonym for
>>
>>feature_t const FEATURE4 = binary<0100>::value;
>>
>>but then "nobody would do that, would they?".
>
>
> It's not the matter of 64 being the same as 0100. It's the matter
> of 100 not being the same as 0100. It simple _cannot_ be resolved
> using any complexity in templates. Period.
I'll elaborate on my sketch of how to resolve it, by showing
that we can define a mapping which takes 0100 and 100 both to
4, and similarly for all other 32-bit values representable as
sums of unique powers of 8, or sums of unique powers of 10.
The question is whether we can tell from a number n in some
range whether it came from an octal literal composed of 0s
and 1s or whether it cam from a decimal literal composed of
0s and 1s.
If that is possible, then we can do it with C++ template
metaprogramming, at least in theory. (And in this case the
practice doesn't look too hard.)
For a 32-bit system, we have to consider powers of 8 up to
8^10 == 2^30, and powers of 10 up to 10^9. There aren't all
that many combinations of either form (sums of distinct
powers of 8, sums of distinct powers of 10) in the range
0..2^32-1, and a quick program can generate all of the
sums of distinct powers of 8 in this range and show that
none of them (except 1) are sums of distinct powers of 10.
So, on 32-bit systems at least, this *is* possible, and can
be resolved using templates.
If you disagree, maybe you can point out the flaw in this
argument.
(I just ran a quick check, and the same holds for 64-bits.)
To be clear, my claim is that the binary class template described
above can be made to work with both decimal and octal strings, at
the expense of accepting some erroneous input, precisely because
TMP can distinguish which has been provided (for currently practical
ranges). Given the existence, for the range in question, of suitable
constructs is_sum_of_distinct_powers_of_8 and
is_sum_of_distinct_powers_of_10, the class template binary can
dispatch using those.
Another approach is to reduce to binary blindly on the expectation
that the number was decimal, and then to expand back to the decimal
equivalent; it that fails, reduce as octal instead.
If that's not good enough, you can wrap the whole thing in a macro
which avoids that problem by pasting "0" onto the front of the
number, forcing it to be octal, before passing to a class template
to do the arithmetic.
-- James
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 8 Nov 2004 18:07:06 GMT Raw View
jdennett@acm.org (James Dennett) writes:
>>> const feature_t FEATURE1 = binary<001>::value;
>>> const feature_t FEATURE2 = binary<010>::value;
>>> const feature_t FEATURE3 = binary<100>::value;
>>>
>> Tricky because 010 and 10 are not the same in C++.
>
> But with our freedom to write (over-)complicated templates,
> that can be handled, by making a template which treats
> 8^n the same as 10^n, where I use ^ as power, not xor.
> (There's no ambiguity except in the case 8^0==10^0==1,
> where the ambiguity is harmless anyway.)
Exactly ;-)
I was wondering when someone would notice that it was possible.
> Of course this would then allow
>
> feature_t const FEATURE4 = binary<64>::value;
>
> as an ugly synonym for
>
> feature_t const FEATURE4 = binary<0100>::value;
>
> but then "nobody would do that, would they?".
Or we could have that cause an error and generate an informative
message.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: rmaddox@isicns.com (Randy Maddox)
Date: Mon, 8 Nov 2004 19:08:12 GMT Raw View
francis@robinton.demon.co.uk (Francis Glassborow) wrote in message news:<Q3srT0AVRhiBFwep@robinton.demon.co.uk>...
> In article <8c8b368d.0411020548.65de2777@posting.google.com>, Randy
> Maddox <rmaddox@isicns.com> writes
> >You mean other than 5.2.9/7, which says:
> >
> >A value of integral or enumeration type can be explicitly converted to
> >an enumeration type. The value is unchanged if the original value is
> >within the range of the enumeration values (7.2). Otherwise, the
> >resulting enumeration value is unspecified.
> >
> >So that, for example, Foo flagUnspecified = flag3 | flag4 yields a
> >value, 12, that is not in the range of Foo enumeration values.
>
> Read 7.2 paragraph 6 which was drafted specifically to ensure that ORing
> all the enumerators resulted in a value within the enumeration range.
>
>
> --
> Francis Glassborow ACCU
> Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
> For project ideas and contributions: http://www.spellen.org/youcandoit/projects
>
Thanks, Francis. I did indeed miss that paragraph.
It does seem a bit odd, however, that it is so easy to create enum
values that cannot be referenced by the enum names. The intent, to
support or'ing together of enum values, make a lot of sense and is
extremely useful, but seems at the same time to conflate the concept
of enumerated values with bit-wise operations that do not fit as well
with some important uses of enums, e.g., as named indexes into a
sequence, as labels in a switch statement, and as parameters of
specified values.
That is, the use of enums as bit flags seems to conflict with other
valid uses of enums since it invalidates the assumption that a value
of an enum type will correspond to one of the eumerated values.
Randy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 9 Nov 2004 00:05:28 GMT Raw View
jdennett@acm.org (James Dennett) writes:
> For a 32-bit system, we have to consider powers of 8 up to
> 8^10 == 2^30, and powers of 10 up to 10^9. There aren't all
> that many combinations of either form (sums of distinct
> powers of 8, sums of distinct powers of 10) in the range
> 0..2^32-1, and a quick program can generate all of the
> sums of distinct powers of 8 in this range and show that
> none of them (except 1) are sums of distinct powers of 10.
>
> So, on 32-bit systems at least, this *is* possible, and can
> be resolved using templates.
>
> If you disagree, maybe you can point out the flaw in this
> argument.
>
> (I just ran a quick check, and the same holds for 64-bits.)
I wonder if it's provable that _no_ such numbers collide in bases 10
and 8, or if it's provable that no such numbers collide in any two
other bases. Even in my halcyon days this was probably beyond my
number theory capability.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: usenet-nospam@nmhq.net (Niklas Matthies)
Date: Tue, 9 Nov 2004 05:03:50 GMT Raw View
On 2004-11-08 02:03, James Dennett wrote:
:
> To be clear, my claim is that the binary class template described
> above can be made to work with both decimal and octal strings, at
> the expense of accepting some erroneous input, precisely because
> TMP can distinguish which has been provided (for currently practical
> ranges).
Correct. Here's my version which goes up to 32 bits (more would
require long long or similar):
// I hope that moderation doesn't break the long lines.
// This compiles under Comeau and is written to also work under VC6.
// I could have used Boost for some pieces, but I prefer standalone.
template <bool b> struct binary_helper_BASE_MUST_BE_8_OR_10;
template <> struct binary_helper_BASE_MUST_BE_8_OR_10<true> { enum { value = 1 }; };
template<unsigned long x> struct binary_helper_BASE_MUST_BE_8_OR_10_ { };
template <unsigned long digits, unsigned int base>
struct binary_helper_
{
// check for valid base:
typedef binary_helper_BASE_MUST_BE_8_OR_10_<sizeof(binary_helper_BASE_MUST_BE_8_OR_10<static_cast<bool>(base == 8 || base == 10)>)> BASE_MUST_BE_8_OR_10;
enum
{
div = digits / base,
rem = digits % base,
value = rem + 2 * binary_helper_<div, base>::value,
is_binary = (rem == 0 || rem == 1) && binary_helper_<div, base>::is_binary
};
};
// template specializations to end the recursion:
template <> struct binary_helper_<0, 8> { enum { value = 0, is_binary = 1 }; };
template <> struct binary_helper_<0, 10> { enum { value = 0, is_binary = 1 }; };
template <bool b> struct binary_octet_NONBINARY_DIGIT_ENCOUNTERED;
template <> struct binary_octet_NONBINARY_DIGIT_ENCOUNTERED<true> { enum { value = 1 }; };
template<unsigned long x> struct binary_octet_NONBINARY_DIGIT_ENCOUNTERED_ { };
template <bool b> struct binary_octet_BINARY_CONSTANT_EXCEEDS_255;
template <> struct binary_octet_BINARY_CONSTANT_EXCEEDS_255<true> { enum { value = 1 }; };
template<unsigned long x> struct binary_octet_BINARY_CONSTANT_EXCEEDS_255_ { };
template <unsigned long digits, unsigned long preceding_octets = 0>
struct binary_octet_
{
enum
{
oct_is_binary = binary_helper_<digits, 8>::is_binary,
dec_is_binary = binary_helper_<digits, 10>::is_binary,
value = binary_helper_<digits, oct_is_binary ? 8 : 10>::value,
result = value + (preceding_octets << 8)
};
// check for non-binary-digits:
typedef binary_octet_NONBINARY_DIGIT_ENCOUNTERED_<sizeof(binary_octet_NONBINARY_DIGIT_ENCOUNTERED<static_cast<bool>(oct_is_binary || dec_is_binary)>)> NONBINARY_DIGIT_ENCOUNTERED;
// check for overflow:
typedef binary_octet_BINARY_CONSTANT_EXCEEDS_255_<sizeof(binary_octet_BINARY_CONSTANT_EXCEEDS_255<static_cast<bool>(value <= 255)>)> BINARY_CONSTANT_EXCEEDS_255;
};
// We use '0ul-1' instead of just '-1' to suppress potential compiler warnings.
template <unsigned long b1, unsigned long b2 = 0ul-1, unsigned long b3 = 0ul-1, unsigned long b4 = 0ul-1>
struct binary
{
enum
{
v3 = binary_octet_<(b4 == 0ul-1 ? b3 == 0ul-1 ? b2 == 0ul-1 ? 0 : 0 : 0 : b1) >::result,
v2 = binary_octet_<(b4 == 0ul-1 ? b3 == 0ul-1 ? b2 == 0ul-1 ? 0 : 0 : b1 : b2), v3>::result,
v1 = binary_octet_<(b4 == 0ul-1 ? b3 == 0ul-1 ? b2 == 0ul-1 ? 0 : b1 : b2 : b3), v2>::result,
v0 = binary_octet_<(b4 == 0ul-1 ? b3 == 0ul-1 ? b2 == 0ul-1 ? b1 : b2 : b3 : b4), v1>::result,
value = v0
};
};
Usage:
int const flags1 = binary<101010>::value; // = 42
enum
{
flags2 = binary<11110000, 00001111, 00110011, 10101010>::value // = 0xf00f33aa
};
And if that syntax is still deemed too unwieldy and you don't mind
macros:
// provides boost-pp-seq-like variadic syntax:
template <unsigned long b1> struct binary_macro_1_ { enum { BINARY_MACR0_1_ = binary<b1>::value };
template <unsigned long b2> struct binary_macro_2_ { enum { BINARY_MACR0_2_ = binary<b1, b2>::value };
template <unsigned long b3> struct binary_macro_3_ { enum { BINARY_MACR0_3_ = binary<b1, b2, b3>::value };
template <unsigned long b4> struct binary_macro_4_ { enum { BINARY_MACR0_4_ = binary<b1, b2, b3, b4>::value }; }; }; }; };
#define BINARY_MACRO_0_(_) binary_macro_1_<_>::BINARY_MACR0_1_
#define BINARY_MACR0_1_(_) binary_macro_2_<_>::BINARY_MACR0_2_
#define BINARY_MACR0_2_(_) binary_macro_3_<_>::BINARY_MACR0_3_
#define BINARY_MACR0_3_(_) binary_macro_4_<_>::BINARY_MACR0_4_
#define B(_) BINARY_MACRO_0_(_)
Usage:
int const flags1 = B(101010); // = 42
enum
{
flags2 = B(11110000)(00001111)(00110011)(10101010) // = 0xf00f33aa
};
-- Niklas Matthies
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: laurie.cheers@btinternet.com (Laurie Cheers)
Date: Tue, 9 Nov 2004 16:41:16 GMT Raw View
dave@boost-consulting.com (David Abrahams) wrote in message news:<u7jow5x62.fsf@boost-consulting.com>...
> jdennett@acm.org (James Dennett) writes:
>
> > For a 32-bit system, we have to consider powers of 8 up to
> > 8^10 == 2^30, and powers of 10 up to 10^9. There aren't all
> > that many combinations of either form (sums of distinct
> > powers of 8, sums of distinct powers of 10) in the range
> > 0..2^32-1, and a quick program can generate all of the
> > sums of distinct powers of 8 in this range and show that
> > none of them (except 1) are sums of distinct powers of 10.
> >
> > So, on 32-bit systems at least, this *is* possible, and can
> > be resolved using templates.
> >
> > If you disagree, maybe you can point out the flaw in this
> > argument.
> >
> > (I just ran a quick check, and the same holds for 64-bits.)
>
> I wonder if it's provable that _no_ such numbers collide in bases 10
> and 8, or if it's provable that no such numbers collide in any two
> other bases. Even in my halcyon days this was probably beyond my
> number theory capability.
Yes, it's provable. It's not even that complicated:
Any power of 10 (except 0) is divisible by 5. No power of 8 is divisible by 5.
So it's trivial to see that if we disregard 10^0, no sum of powers of 10
can be confused with a sum of powers of 8.
As for the 10^0 case, well, we can detect that. If the number is odd,
subtract 1 and the situation reduces to the one above.
Of course this doesn't hold for all bases. For example, 1000 in binary is the
same as 010 in octal.
--
Laurie Cheers
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Tue, 9 Nov 2004 17:59:26 GMT Raw View
In article <u7jow5x62.fsf@boost-consulting.com>, David Abrahams
<dave@boost-consulting.com> writes
>> For a 32-bit system, we have to consider powers of 8 up to
>> 8^10 == 2^30, and powers of 10 up to 10^9. There aren't all
>> that many combinations of either form (sums of distinct
>> powers of 8, sums of distinct powers of 10) in the range
>> 0..2^32-1, and a quick program can generate all of the
>> sums of distinct powers of 8 in this range and show that
>> none of them (except 1) are sums of distinct powers of 10.
>>
>> So, on 32-bit systems at least, this *is* possible, and can
>> be resolved using templates.
>>
>> If you disagree, maybe you can point out the flaw in this
>> argument.
>>
>> (I just ran a quick check, and the same holds for 64-bits.)
I am trying to understand this issue. Is the hypothesis that that there
are no numbers whose representations in base eight and base ten are
limited to the 'digits' '0' and '1'? I.e. that the octal representation
of any value whose decimal representation uses only zeros and ones will
use at least one 'digit' that is neither a zero nor a one.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: tannhauser86549spam@free.fr (=?ISO-8859-1?Q?Falk_Tannh=E4user?=)
Date: Tue, 9 Nov 2004 23:23:16 GMT Raw View
James Dennett wrote:
> If that's not good enough, you can wrap the whole thing in a macro
> which avoids that problem by pasting "0" onto the front of the
> number, forcing it to be octal, before passing to a class template
> to do the arithmetic.
This seems by far the easiest solution to me:
________________________________________________________________________________
template<unsigned long N>
struct octal_to_binary_helper
{
static unsigned long const value = octal_to_binary_helper<N/8>::value<<1 | N%8;
typedef char check_for_bad_digits[N%8 < 2]; // Only '0' or '1' are allowed
};
template<>
struct octal_to_binary_helper<0>
{
static unsigned long const value = 0;
};
#define BIN(n) (octal_to_binary_helper<0##n##UL>::value)
________________________________________________________________________________
Since 'unsigned long' is guaranteed to have at least 32 bits, this would be
guaranteed to work for up to 11 digits (8^0 ... 8^10). With 64-bit integers
(which will hopefully become part of C++ in the future - above code already
works with GCC with 'unsigned long long' and 'ULL' integer literal suffix),
the range would extent to 22 digits (8^0 ... 8^21) - that would unfortunately
still not be enough for all possible applications where one wants to use
binary integer literals...
Hopefully, the compiler will detect "out of range" literals"!
Falk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 9 Nov 2004 23:23:19 GMT Raw View
laurie.cheers@btinternet.com (Laurie Cheers) writes:
>> I wonder if it's provable that _no_ such numbers collide in bases 10
>> and 8, or if it's provable that no such numbers collide in any two
>> other bases. Even in my halcyon days this was probably beyond my
>> number theory capability.
>
> Yes, it's provable. It's not even that complicated:
> Any power of 10 (except 0) is divisible by 5. No power of 8 is divisible by 5.
> So it's trivial to see that if we disregard 10^0, no sum of powers of 10
> can be confused with a sum of powers of 8.
>
> As for the 10^0 case, well, we can detect that. If the number is odd,
> subtract 1 and the situation reduces to the one above.
>
>
> Of course this doesn't hold for all bases. For example, 1000 in binary is the
> same as 010 in octal.
When someone really smart shows it, it always looks so simple ;-)
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 9 Nov 2004 23:24:03 GMT Raw View
francis@robinton.demon.co.uk (Francis Glassborow) writes:
> I am trying to understand this issue. Is the hypothesis that that
> there are no numbers whose representations in base eight and base ten
> are limited to the 'digits' '0' and '1'? I.e. that the octal
> representation of any value whose decimal representation uses only
> zeros and ones will use at least one 'digit' that is neither a zero
> nor a one.
Right. Nicely proven by Laurie Cheers.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]