Are these the best set of bitset macros in the world or what!?

B

Brian

Nick said:
Nick said:
On 16 Sep, 09:16, "Brian" <BWeird!@internet.> wrote:
[...] I don't usually post code because it's all really "top
secret"
you program missiles?!
but I think it [bit manipulation] should be
fixed once and then used "forever" rather than dealt with at every
line of code for that is a waste of human effort and money.
yes, this is correct. A set of bit handling abstractions *is* a good
idea if your code is doing a lot of bit manipulation. Where did you
get the idea that anyone was disagreeing. Where we part company is
if your macros are powerful (they aren't, they are trivial),

It's just bit twiddling. How "powerful" can they be?!

well I guess you posted em for a reason. I assummed there was some
implied significance. I was thinking of "bit streams" where you can
write multiple bits.

I thought it was obvious where they are useful and even gave an example
in the original post. Some may call that premature optimization maybe but
it is done for more reason than just the space efficiency.
fair enough



ah, the missiles. These are not the missiles I am looking for...


you build on the standard stuff when you can.

Wrong, I do not. I used to, but that was many years ago. It's a common
failing, IMO, to buy into things without thinking about them enough. It
takes years to "get it" and most probably never will or become
evangelical about it along with "the group". The best way to learn how to
write software for the long term is to replace as much of the canned
stuff as possible. Even if done just from a learning perspective.
Then your extension/
abstraction is portable.

No, it's just standard. There are many ways to improve on standard APIs.
The standard is just the starting point, a means, not an end, and it's
not "all or nothing" either: use as much or as little as you feel is
appropriate.
In what sense is either standard "sub-
optimal"?


I admit C looked pretty strange when I started to use it.

Back when I first started using it (1989), I thought it was the best
thing since sliced bread, for all of my contemporaries were using
FORTRAN, and the IT guys were doing BASIC (a few years later?), and the
noobs from college were doing Pascal (I learned Pascal in college too,
along with FORTRAN, but never used them much even though FORTRAN was the
major codebase where I worked). The data acq guys were doing C though in
a big way and I had some ambition to get involved with that at the time
and I did write some data reduction programs that ran on their platforms.
I actually was glad that MS embraced standard C in addition to their APIs
and thought that was the way to go at the time, but I have long since
reconsidered and now build on top of the platform APIs rather than
standard C/C++ whenever possible. That said, I have been building my own
abstractions and constructs for years and am now taking it to the moon
(knock on wood).
You get used
to it. You'd be much better off persisting with the standard syntax
rather than hiding it. You'll be able to read other peoples' code and
they'll be able to read yours.

Reading anyone's C code is an excruciating experience. Ever heard the
phrase "C is a write-only language"? Just try to understand, use or reuse
any open source project code that isn't a libary.
so why post it? Were you expecting a gasp of universal astonishment at
your amazing code?

Of course! ;) How about those names! They should be in the standard! ;)
my rule is if there is a standard way of doing something and a non-
standard way of doing it then choose the standard way.

That's fine. That's a popular approach. "No one ever got fired for doing
it like everyone else".
Note this
doesn't exclude the use of libraries and other abstractions built on
top of the standard language and library.

That's another can of worms. It's one thing to actually use the standard
library, and quite another to build on it. I put the standard libs in 3rd
or 4th place after (in no particular order): the platform APIs, my own
APIs, someone else's APIs.

That's probably what these were based on. Or maybe FreeBSD? They are very
old but I redid them last week and I think I like the result. I posted
them up untested, but the gist of it is what I was trying to convey. I
have nice arbitrary-length bitset macros too.
 
B

Brian

Ian said:
And again:

"No dogma for me please. I don't care what standard anyone else uses
and they shouldn't care what my standards are."

Deal with it, I don't want to join your religion and no amount of insult
will make me change my mind.
 
I

Ian Collins

That's another can of worms. It's one thing to actually use the standard
library, and quite another to build on it. I put the standard libs in 3rd
or 4th place after (in no particular order): the platform APIs, my own
APIs, someone else's APIs.

So what do you think the platform APIs are built on, sand?
 
J

James Dow Allen

I think you've got it the wrong way.  It's little-endian machines that
are consistent in this respect.

This confused me for a while. But I now realize we're BOTH right!!
It all depends on how you number the bits.

Big-endian machines work "properly" according to the
above criterion with Bit 0 = MSB and so on.
Little-endian machines work properly with Bit 0 = LSB.
(Which is "better" is a topic for another thread
in another forum, probably after too many drinks.)
Anyway, the only portable way is to access the array with unsigned char.

My concern arose in an application where fastest possible
speed is my highest priority (though I *do* want "my cake
and to eat it too" for readability and portability as possible!)

James
 
B

BartC

Besides 'and' is 3 characters while '&&' is only 2.
That's a 33.3% savings in both time and space.

You forgot the extra white-space that 'and' might demand: 'a and b' versus
'a&&b'. So 60% savings. Or 150% more typing, if you put it the other way.

On the other hand, some people can type English words much more easily, and
with fewer errors, than punctuation.
 
B

Brian

pete said:
Brian said:
Keith said:
Eric Sosman wrote:
[...]
- What is the type of `1'?

I would assume it would be "coerced" to the type of n, yes? [...]

The type of 1 is int.

No matter what the type of n is?

Correct.

In ((a) << (n)),
the types of (a) and (n) are unrelated.

I find that non-regular and surprising and a good reason for hiding it
behind some macros.
 
E

Eric Sosman

Eric said:
Barry Schwarz wrote:
[...]
And what happens if you want to test the sign bit? You might avoid
syntax errors and undefined behavior with
#define bit(n) (1u<< (n))

While I don't see the need, some might even want 1lu or 1llu.

OK on 1u. But the compiler wouldn't really change to signed if an
unsigned was passed (guaranteed with use of the bitsetX defines
below), would it?

You're *still* not seeing the problem, are you? All, right,
let's go through it step by step:

- What is the type of `1'?

I would assume it would be "coerced" to the type of n, yes?

No.
I would assume it would be "coerced" to the type of n, yes? OK, not for
the uint8 and uint16: C's conversion/promotion rules suck rocks.

Since you don't know those rules, your opinion of them is worthless.
Good
thing I have these macros to make things less error-prone than the raw
syntax. A hundred more of them and C may even be turned into something
good.

You've demonstrated that you don't know C, that you're a novice
who makes novice errors -- and renders uninformed novice opinions.

No answer?

No answer?

No answer? All these questions are too hard for you?

(Side note: I was wrong here. It's not the annotations' phrase,
but the holy text of the Eighth Commandment itself.)
Try something new. You'll like it (unless you like vi!). C is an
impediment to understanding that's why a programmer needs macros to make
it understandable.

Years ago when I was young and stupid, my own BNITU was

#define until(x) while(!(x))

.... but I soon outgrew that puerile stage.
 
B

Brian

pete said:
That (1) would be better if it were unsigned, (1u).

That has been noted, that's the other post you already replied to, but
thx.
This might be faster: (1u & (x) >> (n))

But less understandable. Whether the performance would matter for other
uses would have to be decided. I am not currently using them in anything
requiring an optimization.
 
B

Brian

Eric said:
Eric said:
On 9/15/2010 11:06 PM, Brian wrote:
Barry Schwarz wrote:
[...]
And what happens if you want to test the sign bit? You might
avoid syntax errors and undefined behavior with
#define bit(n) (1u<< (n))

While I don't see the need, some might even want 1lu or 1llu.

OK on 1u. But the compiler wouldn't really change to signed if an
unsigned was passed (guaranteed with use of the bitsetX defines
below), would it?

You're *still* not seeing the problem, are you? All, right,
let's go through it step by step:

- What is the type of `1'?

I would assume it would be "coerced" to the type of n, yes?
No.

I would assume it would be "coerced" to the type of n, yes? OK, not
for the uint8 and uint16: C's conversion/promotion rules suck rocks.

Since you don't know those rules, your opinion of them is
worthless.
Good
thing I have these macros to make things less error-prone than the
raw syntax. A hundred more of them and C may even be turned into
something good.

You've demonstrated that you don't know C, that you're a novice
who makes novice errors -- and renders uninformed novice opinions.

No answer?

No answer?

No answer? All these questions are too hard for you?

(Side note: I was wrong here. It's not the annotations' phrase,
but the holy text of the Eighth Commandment itself.)
Try something new. You'll like it (unless you like vi!). C is an
impediment to understanding that's why a programmer needs macros to
make it understandable.

Years ago when I was young and stupid, my own BNITU was

#define until(x) while(!(x))

... but I soon outgrew that puerile stage.

It's about way more than twiddling bits, but you'll probably never get
past that.
 
B

Brian

Eric said:
Eric said:
On 9/15/2010 11:06 PM, Brian wrote:
Barry Schwarz wrote:
[...]
And what happens if you want to test the sign bit? You might
avoid syntax errors and undefined behavior with
#define bit(n) (1u<< (n))

While I don't see the need, some might even want 1lu or 1llu.

OK on 1u. But the compiler wouldn't really change to signed if an
unsigned was passed (guaranteed with use of the bitsetX defines
below), would it?

You're *still* not seeing the problem, are you? All, right,
let's go through it step by step:

- What is the type of `1'?

I would assume it would be "coerced" to the type of n, yes?
No.

I would assume it would be "coerced" to the type of n, yes? OK, not
for the uint8 and uint16: C's conversion/promotion rules suck rocks.

Since you don't know those rules, your opinion of them is
worthless.
Good
thing I have these macros to make things less error-prone than the
raw syntax. A hundred more of them and C may even be turned into
something good.

You've demonstrated that you don't know C, that you're a novice
who makes novice errors -- and renders uninformed novice opinions.

No answer?

No answer?

No answer? All these questions are too hard for you?

(Side note: I was wrong here. It's not the annotations' phrase,
but the holy text of the Eighth Commandment itself.)
Try something new. You'll like it (unless you like vi!). C is an
impediment to understanding that's why a programmer needs macros to
make it understandable.

Years ago when I was young and stupid, my own BNITU was

#define until(x) while(!(x))

... but I soon outgrew that puerile stage.

With no due respect, go **** yourself maggot bit twiddler.
 
E

Eric Sosman

I was obviously not looking at my own code as the free-standing macros
obviously don't don't pass the bitsetX things to bitn. Find the post
where I showed the inline function that uses the low-level macros to good
effect and you'll better understand the usage of the macros.

Haven't time to wade through forty-odd posts to find the piece
of code you refer to, so I'll offer my own example instead:

#define bitn(n) (1<< n) /* your macro, verbatim */
#include <stdint.h>
typedef uint64_t bitset64;
...
uint64_t bit0 = bitn(0); /* works */
uint64_t bit14 = bitn(14); /* works */
uint64_t bit15 = bitn(15); /* works only probably */
uint64_t bit31 = bitn(31); /* works only probably */
uint64_t bit32 = bitn(32); /* almost certainly fails */
uint64_t bit33 = bitn(33); /* almost certainly fails */
...
uint64_t bit63 = bitn(33); /* almost certainly fails */

Final score: 23% guaranteed successes, 27% additional successes if
you're lucky, 50% almost certain failures. That's what I understand
about your macros: They're guaranteed correct in less than one-quarter
of their intended use cases.
 
N

Nick Keighley

you didn't give any expansion on this
Wrong, I do not.

I meant "one builds on the standard stuff..."
I used to, but that was many years ago. It's a common
failing, IMO, to buy into things without thinking about them enough.

it's also a common thing to reinvent (unnecessary) wheels. Sometimes
it's a good idea. Some people have built better string libraries.
It
takes years to "get it" and most probably never will or become
evangelical about it along with "the group". The best way to learn how to
write software for the long term is to replace as much of the canned
stuff as possible. Even if done just from a learning perspective.

well we'll have to disagree here
No, it's just standard.

if it's standard it'll tend to be portable. If you move it from
Windows to Linux and you've avoided too many platform specific APIs
(or encapsulated them well) then porting will be easier
There are many ways to improve on standard APIs.

for instance?
The standard is just the starting point, a means, not an end, and it's
not "all or nothing" either: use as much or as little as you feel is
appropriate.

I actually was glad that MS embraced standard C in addition to their APIs
and thought that was the way to go at the time, but I have long since
reconsidered and now build on top of the platform APIs rather than
standard C/C++ whenever possible.

our experiences differ.

Reading anyone's C code is an excruciating experience.

not always. Well written C is quite readable.

Ever heard the
phrase "C is a write-only language"?

not really. I've heard of write-only programs, and seem some C that
was close to it. But it isn't by any means universal.
Just try to understand, use or reuse
any open source project code that isn't a libary.


That's fine. That's a popular approach. "No one ever got fired for doing
it like everyone else".

that's perilously close to misquoting me

That's another can of worms. It's one thing to actually use the standard
library, and quite another to build on it. I put the standard libs in 3rd
or 4th place after (in no particular order): the platform APIs, my own
APIs, someone else's APIs.

very much depends on the "someone else"

<snip>
 
B

BartC

Years ago when I was young and stupid, my own BNITU was

#define until(x) while(!(x))

... but I soon outgrew that puerile stage.

Presumably this was not a good idea because other people wouldn't have that
macro defined, or were using their own macro for it, or might be using the
identifier for something else entirely.

But, the fact that people consider using such constructions shows there is a
place for them in the language.

And this is one of dozens of minor enhancements that can be added to a
language at virtually no cost (apart from losing 'until' as an identifier,
but that would have been even more reason to have added it early on).
my own BNITU was

Is this another example? Because it's not a very good one..
 
B

Ben Bacarisse

Brian said:
That has been noted, that's the other post you already replied to, but
thx.


But less understandable.

I don't think that's clear-cut. Either way, I think it's a small
difference if there is any.

But pete is selling his version short. More important than the speed is
the fact that his version works no matter how wide the type of x. It
means you can change from, say, unsigned char to uint64_t without having
to remember to change the '1' in bitn.

<snip>
 
S

Seebs

you want to *avoid* standard headers?! Why for deity's sake?

Because he thinks he can do better. As a result of which, he has been
forced to accept a few minor issues:

* He can never move to a different operating system or upgrade his
compiler.
* He can never write code other people can use.
* He can never use code other people have written.

On the bright side, though, he's working in a language which he currently
feels is cleaner. So he's got that going for him.

-s
 
J

James Dow Allen

C has eleven funny-looking operators. Spend eleven hours,
or whatever it takes, to learn those eleven operators.
Once you've done that, you'll find C to be a remarkably
simple language.

Surely you are joking! Give each to a student in programming 101 without
any instruction and see the results. You don't need to have the car
engine exposed to drive the car. Low-level cryptics are not important,
productivity is. Abstraction rules (else use machine language directly).

To read the setbit() form, I have to remember the
order of the arguments and the numbering of the
bits. You may consider these obvious, but in another
message in this thread it was mentioned that the
opposite bit ordering might be useful. (You yourself
implied "1 << n - 1" might be preferred to "1 << n".)

To read the second formula one only has to know C.
" |= " and " << " may indeed seem obscure, but THEY AREN'T
OBSCURE TO ANYONE WHO KNOWS C, or is making a sincere
effort to learn it. Do you see? MINIMIZING what you
need to remember is a worthy goal; if you're unwilling
to remember enough C to understand the second formula
you're not serious.

Saving ink can be worthwhile. I don't know about Ben,
but I have no problem with
#define SETBIT(p, n) ((p)[(n)/8] |= 1 << (n)%8)
The right-side is easily decoded, but the left-side
saves reading time if used frequently.
In Ben's example, however, the ordinary C actually
uses less ink than the macro.

I will agree I prefer your setbit() macro better (once
its bugs are fixed) over your
#define eq ==
That one's just plain silly. You practice a language
no one else in the world uses, and thereby lose the
opportunity to practice reading anyone else's C code.

(If it does amuse you to code that way in your own
boudoir, do yourself a favor. Run your code through
a 'cc -E' or some such before posting it here.
Believe us: no one will be impressed with your clever
code otherwise.)

James Dow Allen
 
S

Shao Miller

Brian said:
Seebs wrote:

[snip]

Your entire post and every "point" in it was a strawman. (Seems to be a
pattern in this ng, for I've found 2 in just reading very few posts. I
hope you and the other guy are just squeeky wheels and not representative
of the whole group).

I think that bit manipulation macros have a use, in general. I don't
know that yours are the very best. If they included documentation and
attempted to avoid identifier collisions, I think they'd be even better.
A personal aesthetic preference of mine is that macro identifiers use
all upper-case, but that's not a universal preference. It's possible
that you could incorporate some of the feedback in the thread thus far
into the macros and offer a version #2 (or #3, since I think you did
already note some improvements based on feedback), and change from "Are
these..." to "Ok, are THESE..." :)

I believe that people who publicly filter ("plonk") you are attempting
to protect themselves against wasting their time in discussion they
mightn't be interested in and/or attempting to publicly advertise their
opinion that you are not worth C discussion.

But if you carry on posting to this newsgroup, you might be surprised to
find that a plonker replies to replies of your posts and might even
continue to portray you in negative ways, regardless of the brevity of
your previous, pre-plonk interaction... It's bullying. You might find
yourself portrayed as a person with characteristics that you do not
agree with.

Have a look at any of your plonkers' signatures. See if you can find a
Wikipedia link. What does its inclusion suggest to you? Just something
to keep in mind.

Fortunately, there appears to be a lot of intelligence in the forum, and
perhaps more forgiveness with some subscribers than with others.
Interestingly, the regular posters do not resemble a "gang" which
automatically plonks when one regular poster plonks; a demonstration of
autonomy and a measure of insurance that even if someone, perhaps
yourself, is disagreeable in discussion about C, anything you offer that
might be valuable might be noticed, discussed, clarified, refined,
referenced, dismissed, dealt with, or whatever.

Have a nice day.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,085
Messages
2,570,597
Members
47,218
Latest member
GracieDebo

Latest Threads

Top