Integer overflow

From Rosetta Code
Revision as of 17:50, 29 July 2014 by rosettacode>Georg Peter (Add task description and 3 languages)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Integer overflow is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Some languages support one or more integer types of the underlying processor. This integer types have fixed size. Usually 8-bit, 16-bit, 32-bit or 64-bit. The integers supported by such a type can be signed or unsigned. Arithmetic for machine level integers can often be done by single CPU instructions. This allows high performance and is the main reason to support machine level integers.

An integer overflow happens when the result of a computation does not fit into the fixed size integer. The result can be too small or too big to be representable in the fixed size integer.

When a language has fixed size integer types, the task is to write a program that does arithmetic compitations for the fixed size integers of the language. This computations must be done such that the result would overflow. The program should demonstate what the following expressions do. For 32-bit signed integers:

   -(-2147483647-1)
   2000000000 + 2000000000
   -2147483647 - 2147483647
   46341 * 46341
   (-2147483647-1) / -1

For 64-bit signed integers:

   -(-9223372036854775807-1)
   5000000000000000000+5000000000000000000
   -9223372036854775807 - 9223372036854775807
   3037000500 * 3037000500
   (-9223372036854775807-1) / -1

For 32-bit unsigned integers:

   -4294967295
   3000000000 + 3000000000
   2147483647 - 4294967295
   65537 * 65537

For 64-bit unsigned integers:

   -18446744073709551615
   10000000000000000000 + 10000000000000000000
   9223372036854775807 - 18446744073709551615
   4294967296 * 4294967296

When the integer overflow does trigger an exception show how the exception is catched. When the integer overflow produces some value print it. This should be done for signed and unsigned integers of various sizes supported by the language. When a language has no fixed size integer type or when no integer overflow can occur for other reasons this should be noted. It is okay to mention, when a language supports unlimited precision integers, but this task is NOT the place to demonstrate the capabilities of unlimited precision integers.

C

C supports integer types of various sizes with and without signedness. Unsigned integer aritmethic is defined to be modulus a power of two. An overflow for signed integer arithmetic is undefined behavior. <lang c>#include <stdio.h>

int main (int argc, char *argv[]) {

 printf("Signed 32-bit:\n");
 printf("%d\n", -(-2147483647-1));
 printf("%d\n", 2000000000 + 2000000000);
 printf("%d\n", -2147483647 - 2147483647);
 printf("%d\n", 46341 * 46341);
 printf("%d\n", (-2147483647-1) / -1);
 printf("Signed 64-bit:\n");
 printf("%ld\n", -(-9223372036854775807-1));
 printf("%ld\n", 5000000000000000000+5000000000000000000);
 printf("%ld\n", -9223372036854775807 - 9223372036854775807);
 printf("%ld\n", 3037000500 * 3037000500);
 printf("%ld\n", (-9223372036854775807-1) / -1);
 printf("Unsigned 32-bit:\n");
 printf("%u\n", -4294967295U);
 printf("%u\n", 3000000000U + 3000000000U);
 printf("%u\n", 2147483647U - 4294967295U);
 printf("%u\n", 65537U * 65537U);
 printf("Unsigned 64-bit:\n");
 printf("%lu\n", -18446744073709551615LU);
 printf("%lu\n", 10000000000000000000LU + 10000000000000000000LU);
 printf("%lu\n", 9223372036854775807LU - 18446744073709551615LU);
 printf("%lu\n", 4294967296LU * 4294967296LU);
 return 0;

}</lang>

Output:
Signed 32-bit:
-2147483648
-294967296
2
-2147479015
-2147483648
Signed 64-bit:
-9223372036854775808
-8446744073709551616
2
-9223372036709301616
-9223372036854775808
Unsigned 32-bit:
1
1705032704
2147483648
131073
Unsigned 64-bit:
1
1553255926290448384
9223372036854775808
0

Java

The type int is a signed 32-bit integer and the type long is a 64-bit integer. <lang java>public class integerOverflow {

   public static void main(String[] args) {
       System.out.println("Signed 32-bit:");
       System.out.println(-(-2147483647-1));
       System.out.println(2000000000 + 2000000000);
       System.out.println(-2147483647 - 2147483647);
       System.out.println(46341 * 46341);
       System.out.println((-2147483647-1) / -1);
       System.out.println("Signed 64-bit:");
       System.out.println(-(-9223372036854775807L-1));
       System.out.println(5000000000000000000L+5000000000000000000L);
       System.out.println(-9223372036854775807L - 9223372036854775807L);
       System.out.println(3037000500L * 3037000500L);
       System.out.println((-9223372036854775807L-1) / -1);
   }

}</lang>

Output:
Signed 32-bit:
-2147483648
-294967296
2
-2147479015
-2147483648
Signed 64-bit:
-9223372036854775808
-8446744073709551616
2
-9223372036709301616
-9223372036854775808

Seed7

Seed7 supports unlimited precision integers with the type bigInteger. The type integer is a 64-bit signed integer type. All computations with the type integer are checked for overflow. The program below surrounds every writeln statement with a block. Normally much larger blocks would be used. <lang seed7>$ include "seed7_05.s7i";

const proc: main is func

 begin
   block
     writeln(-(-9223372036854775807-1));
   exception
     catch OVERFLOW_ERROR:
       writeln("OVERFLOW_ERROR");
   end block;
   block
     writeln(5000000000000000000+5000000000000000000);
   exception
     catch OVERFLOW_ERROR:
       writeln("OVERFLOW_ERROR");
   end block;
   block
     writeln(-9223372036854775807 - 9223372036854775807);
   exception
     catch OVERFLOW_ERROR:
       writeln("OVERFLOW_ERROR");
   end block;
   block
     writeln(3037000500 * 3037000500);
   exception
     catch OVERFLOW_ERROR:
       writeln("OVERFLOW_ERROR");
   end block;
   block
     writeln((-9223372036854775807-1) div -1);
   exception
     catch OVERFLOW_ERROR:
       writeln("OVERFLOW_ERROR");
   end block;
 end func;</lang>
Output:
OVERFLOW_ERROR
OVERFLOW_ERROR
OVERFLOW_ERROR
OVERFLOW_ERROR
OVERFLOW_ERROR