Was kann da schon schiefgehen?
3.1.1Groß plus Klein¶
Klar:
z.B. .
Taschenrechner, Python, andere Programmiersprachen: 0.
1 + 10.5 ** 20 - 10.5 ** 200.0Alternativ:
1 + (10.5 ** 20 - 10.5 ** 20)1.03.1.2Ungenaue Zahlendarstellung¶
Nicht jede Zahl kann im Computer exakt dargestellt werden, was zu unerwarteten Effekten führen kann:
a = 0.1 * 0.1 - 0.01 # sollte theoretisch 0 sein
b = 10 ** 20
a * b173.47234759768073.1.3Patriot-Raketenabwehr¶
Siehe GAO/IMTEC-92-26 Patriot Missile Software Problem.
Kurzfassung:
Zweiter Golfkrieg (“Operation Desert Storm”). US-Amerikanische Militärbasis in Dharan (Saudi-Arabien) wird durch Patriot-Raketenabwehrsystem vor Scud-Raketen aus dem Irak geschützt. Vorher für dieses Szenario nicht wirklich getestet (Steuersoftware aus den 70er-Jahren).
Gelegentlich werden Raketen aus ungeklärten Gründen nicht abgefangen.
Jemand schaut mal nach, wo es klemmt.
Fehler gefunden: Rundungsfehler verstärkt sich im Laufe der Zeit durch ungeschickte Implementierung einer Multiplikation mit 0.1, sodass nach hinreichend langer Up-Time das System nicht mehr präzise genug arbeitet.
Anweisung an die Nutzer: System täglich neu starten.
Software-Update wird am 16. Februar 1991 verfügbar, impliziert aber 2 Stunden Down-Time. Probleme beim Verteilen usw.
Am 25. Februar 1991 sterben 28 US-Soldaten durch eine Scud-Rakete.
Jemand spielt das Update ein am 26. Februar 1991.
Details zum Rundungsfehler: IDV 310.
3.1.4Simulation von Schwingungen¶
Bei der Simulation einer schwingenden Saite kann die Auslenkung der Saite zu diskreten Zeitpunkten berechnet werden. Bei gegebenem Zeitintervall hängt die Brauchbarkeit der Simulation wesentlich von der Anzahl der Zeitschritte ab. Sind die Schritte zu groß, so ist die Simulation nicht mehr stabil (später mehr zu diesem Begriff).
Hier die Simulationen für 200 und 198 Zeitschritte:
Source
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as anim
from IPython.display import HTML
def wave1d(a, T, c, f, nx, nt):
# löst Wellengleichung auf Intervall [0, a] im Zeitraum [0, T] mit
# Wellengeschwindigkeit c und Anfangsauslenkung f
delta_x = a / nx
delta_t = T / nt
C = c * delta_t / delta_x
x = np.linspace(0, a, nx + 1)
u = np.empty((nt + 1, nx + 1), dtype=float)
# Randbedingung
u[:, 0] = 0
u[:, -1] = 0
# Anfangsbedingungen
u[0, :] = f(x)
u[1, 1:-1] = 0.5 * C ** 2 * (u[0, :-2] - 2 * u[0, 1:-1] + u[0, 2:]) + u[0, 1:-1]
# Zeitschritte
for j in range(1, nt):
u[j + 1, 1:-1] = C ** 2 * (u[j, :-2] - 2 * u[j, 1:-1] + u[j, 2:]) \
- (u[j - 1, 1:-1] - 2 * u[j, 1:-1])
return u
def show_anim(u, a, T):
nt = u.shape[0] - 1
nx = u.shape[1] - 1
x = np.linspace(0, a, nx + 1)
# Bildrate auf 25 fps begrenzen
fps_real = nt / T
fps_show = 25
skip_frames = int(np.floor(fps_real / fps_show))
n_frames = (nt + 1) // (skip_frames + 1)
# Figure/Axes erstellen
fig, ax = plt.subplots()
ax.set_xlim(0, a)
ax.set_ylim(-1.1, 1.1)
ax.set_xlabel('x')
ax.set_ylabel('u(x,t)')
ax.grid()
# Linienobjekt erstellen (wird während Animation verändert)
line = ax.plot(0, 0, '-b')[0]
# Update-Funktion
def update(frame):
line.set_data(x, u[(skip_frames + 1) * frame, :])
# Animation erstellen und anzeigen
fa = anim.FuncAnimation(fig, update, frames=n_frames, interval=1000/fps_show)
display(HTML(fa.to_jshtml()))
plt.close() # verhindert automatischen Aufruf von plt.show() durch Jupyter
a = 2
T = 4
c = 1
f = lambda x: np.sin(1/a * np.pi * x)
nx = 100
nt = 200
print(f'{nt} Zeitschritte')
u = wave1d(a, T, c, f, nx, nt)
show_anim(u, a, T)
nt = 198
print(f'{nt} Zeitschritte')
u = wave1d(a, T, c, f, nx, nt)
show_anim(u, a, T)200 Zeitschritte
198 Zeitschritte