lehrkraefte:snr:informatik:bits-and-bytes:ueberraschende-rechnungen

Überraschende Rechnungen

Python bzw. Tigerjython passt auf, wenn die Zahlen zu gross werden, und kann mit recht grossen Zahlen rechnen. Beispielsweise läuft das folgende Programm problemlos:

p = 1
for a in range(36):
    print("2^%d = %d" % (a,p))
    p *= 2

In vielen anderen Sprachen muss man aber aufpassen, beispielsweise in C, wie die folgende Box illustriert.

Unten folgt ein Programm in der Programmiersprache C, das zeigt, dass der Datentyp int alias Integer (vermeintlich ganze Zahl) in Wirklichkeit eine Zahl/Uhrzeit auf der Uhr mit $2^{32}$ Zeiten ist, wobei man die “linke Hälfte” der Uhr als negative Zahlen/Uhrzeiten interpretiert. Mit anderen Worten kann ein Integer in C Werte zwischen $-2^{31} = -2'147'483'648$ und $2^{31}-1 = 2'147'483'647$ annehmen und gerechnet wird modulo $2^{32}=4'294'967'296$.

Hier ist die Ausgabe des Programms (erster Block: Zweierpotenzen, plötzlich negativ, dann Null; zweiter Block: Übergang von der “rechten, positiven Hälfte der Uhr” auf die “linke, negative Hälfte” und später zurück; dritter+vierter Block: ähnlich beim Multiplizieren von Zahlen, die gar nicht schrecklich gross sind):

zwei hoch     0 ist            1
zwei hoch     1 ist            2
zwei hoch     2 ist            4
zwei hoch     3 ist            8
zwei hoch     4 ist           16
zwei hoch     5 ist           32
zwei hoch     6 ist           64
zwei hoch     7 ist          128
zwei hoch     8 ist          256
zwei hoch     9 ist          512
zwei hoch    10 ist         1024
zwei hoch    11 ist         2048
zwei hoch    12 ist         4096
zwei hoch    13 ist         8192
zwei hoch    14 ist        16384
zwei hoch    15 ist        32768
zwei hoch    16 ist        65536
zwei hoch    17 ist       131072
zwei hoch    18 ist       262144
zwei hoch    19 ist       524288
zwei hoch    20 ist      1048576
zwei hoch    21 ist      2097152
zwei hoch    22 ist      4194304
zwei hoch    23 ist      8388608
zwei hoch    24 ist     16777216
zwei hoch    25 ist     33554432
zwei hoch    26 ist     67108864
zwei hoch    27 ist    134217728
zwei hoch    28 ist    268435456
zwei hoch    29 ist    536870912
zwei hoch    30 ist   1073741824
zwei hoch    31 ist  -2147483648
zwei hoch    32 ist            0
zwei hoch    33 ist            0
zwei hoch    34 ist            0
zwei hoch    35 ist            0

  2147483647
 -2147483648
 -2147483647

       32768
       65536

  1073741824
 -2147483648
           0
#include <stdio.h>
 
int main()
{
  int p = 1;
  int a;
  for (a = 0; a < 36; a = a + 1) {
    printf("zwei hoch %5d ist %12d\n", a, p);
    p = p * 2;
  }
  printf("\n");
 
  /* 2 hoch 31 minus 1*/
  int x = 2147483647;
 
  printf("%12d\n", x);
  printf("%12d\n", x+1);
  printf("%12d\n", x+2);
  printf("\n");
 
  /* 2 hoch 15 */
  int m = 32768;
 
  /* 2 hoch 16 */
  int n = 65536;
 
  printf("%12d\n", m);
  printf("%12d\n", n);
 
  printf("\n");
 
  printf("%12d\n", m * m);
  printf("%12d\n", m * n);
  printf("%12d\n", n * n);
 
  return 0;
}
  • Achtung: Rechenfehler beim Rechnen mit Kommazahlen auf dem Computer! (Da der Computer manchmal Nachkommastellen abschneidet, auch wenn man das vom Dezimalsystem her nicht erwarten würde; beispielsweise ist $0,1$ dezimal im Binärsystem eine nicht-abbrechende Kommazahl!)
x = 0.1+0.2
y = 0.3
 
print(x)
print(y)
 
if x==y:
    print("Die beiden Zahlen sind gleich.")
else:
    print("Die beiden Zahlen sind NICHT gleich.")
 
 
print("%.20f" % x)
print("%.20f" % y)
  • lehrkraefte/snr/informatik/bits-and-bytes/ueberraschende-rechnungen.txt
  • Last modified: 2022/02/15 22:47
  • by Olaf Schnürer