Re: function to determine if an integer is divisible by 2
Gennaro Prota wrote:
On Mon, 12 Feb 2007 12:01:44 CST, James Kanze wrote:
I had in mind to use C99's log2 function (actually, the
corresponding three C++ overloads). [...]
I'm not familiar with log2, but what makes you think that it is
immune to rounding errors, say on a machine with base 10
floating point?
Nothing, I just overlooked the case :-)
General rule: never use floating point unless absolutly
necessary:-). And never use it if an exact result is required.
[...]
Flexibility is more difficult: how do you know what types of
flexibility will be needed before the need arises. Premature
genericity is about like premature optimization.
Agreed. But I'm very oriented toward libraries. Almost everything I
need in an application ends up in some sort of reusable solution,
inevitably with some (hopefully reasonable) generalization. Of course
the boundary between reasonableness and "excess" is personal: you
generalized is_power_of_two to is_power_of_n, for instance, and
someone else might find that useless.
The point is that you don't decide which generalization to
implement until you actually need it. You write a simple,
non-template non-generic function: is_power_of_2( int ), and
that's it, until you need more. Then you modify as needed.
Even in a general-purpose library?
Where do the specifications for a general-purpose library come
from? If you just add functions (or functionality) on a hunch
that it might be useful, you'll probably end up with a
no-purpose library. Good general-purpose libraries are born out
of experence, and implement functionality that has really been
needed in a large number of real projects. And this experience
determines the genericity.
(My gut feeling is that what you
say is very wise to do in a MLOC project where the "libraries" are
written for use within the application and developed together with it.
In such contexts, any complication, however little in itself, adds up
to the monster. For a general purpose library, which is what I'm used
to, I'm a less convinced.)
I'd say it's even more important, since you do want to offer
something "useful". Speculating on possible uses is futile;
you'll never hit the nail on the head.
[...] Even the standard libraries has examples of
things meant to allow generalization --custom manipulators for
instance-- which then don't work very well in practice
probably because they were standardized without having
actually been used.
The standard doesn't have custom manipulators---if they're in
the standard, they aren't custom:-). The standard does support
them pretty well, however; I don't think I've ever written an
application which didn't make extensive use of them.
Hmm, I should have said "support for custom manipulators" :-)
Specifically, I was thinking of pword(), xalloc() and stream
callbacks: last time I tried them (some three or four years ago)
storing a UDT to be retrieved by the stream inserter was a pain to get
right.
Memory management can be a pain when complex types are involved
(unless you're using the Boehm collector). In practice,
however, I've never needed dynamically allocated complex types
to control formatting; at most a flag or a small int... or a
pointer to a staticly allocated polymorphic functional object.
(Or... quite frankly, when portability isn't a great
concern---an for 99% of what I do, portability is limited to
Posix/Linux---, I cheat, and store a pointer to function in the
void*.) The use is a bit C-like, in that you have a separate
function (or functional object) and data, but it works pretty
well in practice.
But perhaps I didn't try hard enough: I quickly give up under
the feeling that I was going on thin ice, and I don't recall the
details right now. Certainly I hadn't the impression that there had
been extensive practice with them before they got standardized.
That's a problem with a lot of the standard; had there been any
real practice, iterators would have looked a lot different, for
example, and I'd be very surprised that there'd be templates at
the user level of iostream. On the other hand, there was
extensive practice concerning manipulators, and the general
iostream idiom, which works exceptionally well for what it was
designed to do.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
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
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]