From: "REH" <me@you.com>
Subject: Re: where exactly c++,c fail and Ada gets thru'
Date: Sat, 29 Apr 2006 14:08:18 GMT
Date: 2006-04-29T14:08:18+00:00 [thread overview]
Message-ID: <mrK4g.4748$Gg.3276@twister.nyroc.rr.com> (raw)
In-Reply-To: 1201812.r16X2gYOJE@linux1.krischik.com
"Martin Krischik" <krischik@users.sourceforge.net> wrote in message
news:1201812.r16X2gYOJE@linux1.krischik.com...
> Now I do wonder if REH managed some template/boolean magic to get the same
> result on C++.
>
The simplistic answer is for each ranged type R, there is an intermediate
type I. I has the same properties as R, except it is allowed to "grow."
That is, as the results of partial expressions become large, I chooses an
integer type with a larger range (sadly, my technique will not work with
floating point types). If I is not able to find a type with a larger enough
range, it is flagged has having the possibility of overflowing. The math is
basically done by partial specializing on whether overflow is possible. The
tricky part is determining whether an overflow can occur. For this I took a
page from my COBOL days. If you performed an operation on two values and
tried to shove it into a variable without enough digits, COBOL would warning
you. For example, multiplying two two-digit values and trying to assign it
to anything less than a 4-digit variable can overflow. Of course, it is
trivial to determine this for every algebraic operator. So, for each
operation, we calculate the maximum number of digits needed for the result
and try to use a type with that ranged. The maximum digits is kept in I.
This allows intermediate values to exceed the bounds of the ranged type
(like doing the math using R'Base). When a type I is assigned to type R, it
is ranged check if necessary. If the lower or upper bounds of I is within
the bounds of R, that particular check is also removed. This is all done at
compile time.
As an example, assume R is an unsigned type with a ranged of [0, 100]. The
number of binary digits necessary to hold R is 7. So, if x and y are
variables of type R, then x * y needs at most 14 digits. On any system,
unsigned int can hold a 14-digit number. No overflow can happen, so no
check is done. The result is of type I. I is a class temple whose template
parameters hold information needed at compile-time. I "contains" type
unsigned int, and 14 for the digits. I also "knows" it's base type (R), so
is able to keep types unique. R can be instantiated with or without
explicit construction (defines whether or not conversion to R requires an
explicit cast), and with or without conversion operators (defines whether R
can be implicitly converted to other types). R can bound the largest type
allowed in its calculations. For example, assume we are on a system where
int is 16 bits and long is 32 bits. If we take the resulting value of type
I above and do I * I, this needs a 28-digit type. Normally, the resulting I
type would use unsigned long. R can be bounded to stop at 16-bits if, for
some reason you do not want to use type long. Thus, instead of growing, the
new I would be flagged and the operation would be checked for overflow.
Now, you may ask why I didn't just define I with the resulting range of [0,
1000]. The answer is that it would be a lot nastier because then I would
also have to do overflow checking on the ranges at compile-time. It would
be really nasty for signed types because you cannot just do the operation
and check for overflow. Allowing a signed operation to overflow is
undefined behavior.
The above technique works for both signed and unsigned types, and all three
integer representations allowed by the C++ standard. I'd like to enhance it
to handle floating points, but I currently have no clue how that could be
done. I'll admit the templates are very, very complex, but for the most
part the client software does not have to worry about it. You can just use
you would any other numerical type. I don't recall having any issue with
"error messages" while writing it. Modern C++ compiler have gotten very
good at giving more sane messages. They have also gotten better at compile
times. My ranged type is not perfect, and there is no way to perfectly
replicate what Ada can do, but as I said I cannot always use Ada. I also
realize that the class will never be able to remove as many checks as an Ada
compiler, but it is much better than nothing. The checks are very expensive
since they are done in standard C++ (though one could sacrifice portability
for speed if their compiler supported inline assembly). On benchmarks I've
run, the class can be very close to raw integers in terms of speed, where
not eliminating any checks can cost 10x or more. Of course this all depends
on your system, compiler, etc., and the particular expressions (what the
class can catch). In particular, very complex expressions will saturate the
range of the types available quickly and inhibit anymore optimizations.
Breaking the expression up can help to alleviate this, but each time an I is
assigned to an R, a range check may have to be done (those range checking is
much, much more efficient than overflow checking).
REH
next prev parent reply other threads:[~2006-04-29 14:08 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-04-24 4:19 where exactly c++,c fail and Ada gets thru' Ananth the Boss
2006-04-24 5:05 ` jimmaureenrogers
2006-04-24 7:45 ` Ananth the Boss
2006-04-24 19:17 ` Martin Krischik
2006-04-24 20:23 ` Simon Wright
2006-04-24 22:34 ` Keith Thompson
2006-04-24 22:33 ` Keith Thompson
2006-04-25 5:23 ` Jeffrey R. Carter
2006-04-26 17:48 ` Martin Krischik
2006-04-26 19:33 ` Keith Thompson
2006-04-26 15:10 ` Maciej Sobczak
2006-04-26 17:32 ` Martin Krischik
2006-04-27 10:07 ` Maciej Sobczak
2006-04-27 21:19 ` Keith Thompson
2006-04-28 7:00 ` Martin Krischik
2006-04-28 12:27 ` Maciej Sobczak
2006-04-29 7:03 ` Martin Krischik
2006-04-29 14:08 ` REH [this message]
2006-05-01 10:20 ` Xcriber51
2006-05-01 13:55 ` REH
2006-05-02 6:43 ` Maciej Sobczak
2006-04-27 16:48 ` REH
2006-04-28 7:49 ` Martin Krischik
2006-04-28 11:17 ` REH
2006-04-29 6:47 ` Martin Krischik
2006-04-24 8:13 ` Rod Chapman
2006-04-25 1:57 ` Steve
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox