James Kanze
10/16/2008 9:43:00 AM
On Oct 16, 3:54 am, Stephen Horne <sh006d3...@blueyonder.co.uk> wrote:
> One option you have is to use Ada, which has overflow
> detection built in. You can declare subtypes with different
> ranges, and the overflow check is based on that. Performance
> isn't normally badly hit because the compiler can determine
> when the checks are needed and when they aren't.
I don't think the original poster was looking for Ada-like
overflow checking (although it would be nice as well). He
specifically mentionned the problem of implementing variable
width numbers, and his problem seemed to be that there are
always (or almost always) specific hardware features which would
help here, but which cannot be accessed from C++: every machine
I've worked on has a carry bit, for example, and the vast
majority will calculate a double word result when multiplying
words. Thus, if you're implementing an extended + operator on
an 80x86, your main loop would almost certainly contain
something like:
mov eax, [esi]
adc eax, [ebx]
mov [edi], eax
That adc instruction (add with carry) makes things go a lot
faster, and there's no way to get the C++ compiler to generate
it. (I suppose a really good optimizer could recognize some
pattern in your code, deduce that this was the target semantics,
and generate it. But I've never seen an optimizer that good.)
The case of multiplication is even worse: when multiplying two
32 bit values, you need the full 64 bit results; the hardware
multiply on an 80x86 gives you this, but the compiler won't let
you get at the top 32 bits.
As an extreme example of this sort of problem, I once maintained
a product which used BCD arithmetic; there was a module of
somewhere around 1000 LOC in C which implemented the four basic
operators for 13 digit BCD values. The person who ported this
application to the Siemens BS2000 mainframe (IBM 360
architecture) rewrote this module in assembler. With about 10
machine instructions and no loops for each operator: the
hardware had hardwired 8 byte BCD arthimetic. In this case, the
assembler was not only faster (by several orders of magnitude),
it was also significantlly shorter and simpler to understand and
maintain.
> The main problem with Ada is that it's nowhere near as widely
> used as C++, meaning few third party libraries, limited
> compiler choices etc.
> Within C++, you can use big integer classes or other
> integer-type wrapper classes that either never overflow
> (unless you go really nuts) or which have overflow checks
> built in. Libraries like this can be used pretty much as
> easily as simple integers due to operator overloading.
The problem is that either you write the actual code for such a
class in assembler, or you take a serious performance hit.
Because the hardware has special instructions for this, the
assembler is typically easier to understand and maintain than
the C++ would. As for portability, however...
I rather agree with the original poster. It would be nice if
C++ offered some way to access this funtionality. Practically,
however, I don't really know what the syntax would look like.
--
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