overflow/underflow

overflow/underflow

Post by Kenneth Kasajia » Wed, 21 May 1997 04:00:00



How does one check on overflow/underflow for the following C++ types:
long, short, float, double, for add, subtract, multiply, divide.
Example:
        long L;
        L = 2147483647;
        L++;
        // Check flag to see if it overflowed.

Using assembly language, I can easily accomplish this
under Intel/Win32 via:
        seto al
        mov fOverflow, al

And for floating point, I can use _clearfp( ).

However, this is Microsoft compiler and Intel CPU specific.
How does one do this in plain C++??  Is there a way?

Code samples:

long L;
L = 2147483647;
L++; // overflow after this line?
----
short I;
I = 32767;
I++; // overflow after this line?
----
double d;
d = 1.7976931348623158e+308;
d = d * d; // overflow after this line?
----
float f;
f = 16777216.000000;
f++; // overflow after this line?

Please CC your reply to:


      [ about comp.lang.c++.moderated. First time posters: do this! ]

 
 
 

overflow/underflow

Post by Phlip C Plumle » Thu, 22 May 1997 04:00:00


 Kenneth Kasajian

Quote:>How does one check on overflow/underflow for the following C++ types:
>long, short, float, double, for add, subtract, multiply, divide.
>Example:
> long L;
> L = 2147483647;
> L++;
> // Check flag to see if it overflowed.

<other examples snipped>

define a template called SafeType<class type>

Inside the template put crackers that verify 'type' is a primitive built-in
type and not a derived type. Use 'assert' statements that check RTTI,
'sizeof', etc.

Now define every math operator that native scalar types support; '++', '%',
'<<', etc. Define some of these as free friend functions, so binary
operators balance properly between the left and right sides. Also give your
template a conversion operator that converts to the base type.

And inside each operator use the standard library's "traits" templates to
ensure the result of an operation did not excede the base type's limits.
Make sure to include the assignment operator.

Check the C++ literature to make sure you match the "canonical types" of
all operators. 'operator==', for example, will be 'bool operator==
(SafeType<type> const &r, SafeType<type> const &h)', not 'int operator==
(SafeType<type> &r, SafeType<type> &h)'.

Now the real decision comes.

You can either check for overflow using 'assert', or 'throw'. This was the
decision the authors of the software piloting the Ariane V faced. They

) for dissertations on the Ariane V rocket.

If you use 'assert', the statements disappear when you compile for release.
This means your debug system has to execute every possible call tree that
your program in the field might face. But your final program will be really
small and fast. If I wrote compilers I would write them like this - all we
need to test is a humongous set of files of source code - we turn on a MAKE
program and wander away while the debug version of our program tests
everything.

If you use 'throw', your release program is just a little bigger and
slower. And you must write code somewhere that '
catch's, and does something non-useless so the program recovers. You
effectively have more program control paths to test now, and every line of
this code must be "exception safe". This is the tack I would take if I was
writing the hardware controller for a vehicle, power plant or rocket.

  --  Phlip
======= http://users.deltanet.com/~tegan/home.html =======
  --  Just Say No to Teamwork!  --


      [ about comp.lang.c++.moderated. First time posters: do this! ]

 
 
 

overflow/underflow

Post by James Kanz » Fri, 23 May 1997 04:00:00


|>  How does one check on overflow/underflow for the following C++
types:
|>  long, short, float, double, for add, subtract, multiply, divide.
|>  Example:
|>   long L;
|>   L = 2147483647;
|>   L++;
|>   // Check flag to see if it overflowed.
|>  
|>  Using assembly language, I can easily accomplish this
|>  under Intel/Win32 via:
|>   seto al
|>   mov fOverflow, al
|>  
|>  And for floating point, I can use _clearfp( ).
|>  
|>  However, this is Microsoft compiler and Intel CPU specific.
|>  How does one do this in plain C++??  Is there a way?

One doesn't.  There is no way to test whether an operation has
overflowed in C++.  The normal technique for safe programming is to test
whether the operation will overflow, before executing it.  Thus, for
int:

        int                 i ;
        if ( i < INT_MAX )
                ++ i ;
        else
                //  Generate error.

Doing such checks before every individual operation is anything but
cheap.  In many cases, however, you should be able to propagate them
out: i.e.: if the input arguments meet such and such criteria, the
following operations cannot overflow, and then check the criteria before
executing a whole set of operations.  This is the solution I normally
use.

BTW: although it isn't a problem for increment, you generally have to be
careful as to how you formulate your control expressions, in order to be
sure that they don't overflow either.

--

62

54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles
France
            -- Conseils en informatique industrielle --


      [ about comp.lang.c++.moderated. First time posters: do this! ]