[M3devel] integer overflow

Jay K jay.krell at cornell.edu
Tue Jan 12 10:23:00 CET 2010


I propose that integer signed overflow always raise an immediate exception.

Word.T should either raise an exception for unsigned overflow, or maybe no exceptions at all.

For folks that want silent wraparound, maybe a separate interface like UnsafeInt.

 

 

I propose that FloatMode's integer features not be the way forward.

 

 

There are two implementation strategies.

 

 

 - "check the carry flag"

   A processor-specific thing, but possibly something easy for the gcc backend to do.

   And very likely easy for the integrated backend.

   Probably very efficient.

 

 

 - internally generate function calls for every arithmetic operation

   like how sets are implemented

 

 

 Implementing most such functions is easy enough in portable C.

 Or maybe using Modula-3 and interface Word.

 

 

 e.g.

   void add(int a, int b, int* c, int* overflow)

   {

    int d = (a + b);

    /* overflow if input signs are equal and output sign is different;

        if input signs are unequal, overflow is not possible

        positive + positive: expect positive, else overflow

        negative + negative: expect negative, else overflow

        positive + negative: overflow not possible */

    *overflow = ((a < 0) == (b < 0) && (d < 0) != (a < 0));

    *c = d;

  }

 

 

   void sub(int a, int b, int* c, int* overflow)

   {

    int d = (a - b);

    /* overflow if input signs are unequal and output sign is different than first input;

        if input signs are equal, overflow is not possible;

        positive - negative: expect positive, overflow if negative

        negative - positive: expect negative, overflow if positive

        positive - positive, negative - negative: overflow not possible */

    *overflow = ((a < 0) != (b < 0) && (d < 0) != (a < 0));

    *c = d;

  }

 

#include <limits.h>

 

  void mult(int a, int b, int* c, int* overflow)

  {

    /* do operation in higher precision and check if it fits */

    int64 d = (a * (int64)b);

    *c = (int)d;

    *overflow = (d >= INT_MIN && d <= INT_MAX);

  }

 

/* for interface Word */

  typedef unsigned uint;

 

  void addu(uint a, uint b, uint* c, int* overflow)

  {

     uint d = (a + b);

    /* overflow if output less than either input */

    *overflow = (d < a);

    *c = d;

 }

 

  void subu(uint a, uint b, uint* c, int* overflow)

  {

     uint d = (a - b);

    /* overflow if output greater than first input */

    *overflow = (d > a);

    *c = d;

 }

 

  void multu(uint a, uint b, uint* c, int* overflow)

  {

    /* operate at higher precision and see if it fits */

     uint64 d = (a * (uint64)b);

    *overflow = (d <= UINT_MAX);

    *c = (uint)d;

 }

 

 void multLU(uint64 a, uint64 b, uint64* c, int* overflow)

 {

  /* break it down into smaller operations, not shown, but not difficult */

 }

 

 

Yes I know this is inefficient, but such is a possible price of portable safety.

 

 

A hybrid is probably possible if the gcc backend support must be processor specific and we gradually provide the implementations.

 

  

 - Jay





 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20100112/9a600909/attachment-0002.html>


More information about the M3devel mailing list