olaf snipped-for-privacy@criseis.ruhr.de> schrieb oder zitierte: : Ich hab z.B Nachrichtentechnik studiert. Da fand :ich vor allem den Umgang mit komplexen Zahlen meines HP48SX EXTREM :praktisch. Ausserdem hatte ich diverse Mathelibaries fuer alles :moegliche drauf und mir auch einige kleinere Sachen selber :programmiert.
Seit zirka 2017 mach ich viel mit Python, und da kann man sich leicht eine Bibliothek schreiben, die zum Beispiel Größen mit Einheiten und Fehlern berechnet. (Komplexe Zahlen werden von Python auch unterstützt - aber meine Bibliothek wurde nicht mit ihnen getestet.)
Als Beispiel wähle ich die Frage: Wie ist für einen Punkt auf der Erdumlaufbahn das Verhältnis der Beschleunigung durch die Erde zu Beschleunigung durch die Sonne, englisch das "Ratio g/a"?
Mein Python-Programm gibt aus:
Ratio g/a = 1655.2346772691253 ± 0.03812014580713078 [dimensionless]
. Also mit Fehler und Einheiten. Die vollständige Ausgabe zeigt die verwendeten Größen:
G = 6.6743e-11 ± 1.5e-15 [m^3 kg^-1 s^-2] Mass of Sun = 1.98847e+30 ± 1e+25 [kg] Distance to Sun (r) = 149668992000.0 ± 0.0 [m] Acceleration towards Sun at r (a) = 0.005924628171867096 ± 1.364445131956885e-07 [m s^-2] Standard gravity on Earth (g) = 9.80665 ± 0.0 [m s^-2] Ratio g/a = 1655.2346772691253 ± 0.03812014580713078 [dimensionless]
Der vollständige Python-3.14-Quellcode ist unten zu finden.
Allerdings nutze ich noch sehr oft die Umrechnung Hex/Dez/Bin und ganz
Ich hatte, grob um 1980 herum, extra einmal dafür einen damals relativ teuren "TI Programmer" gekauft, aber dann praktisch nie benutzt.
Was ich damals auf selbst sonst guten programmierbaren Taschenrechnern vermißt hatte, waren eben solche Umrech- nungen und eine auslesbare Quarzuhr. Der Pet 2001 hatte eine Uhr.
Quellcode für Fehlerrechnung mit Einheiten in Python:
# Copyright 2025 Stefan Ram # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # #
from math import sqrt, isclose import re
SI_UNITS = ['m', 'kg', 's', 'A', 'K', 'mol', 'cd']
class DimFloat: def __init__(self, value, error=0.0, dims=None): self.value = float(value) self.error = float(error) # dims: tuple/list of 7 ints, one per SI base unit if dims is None: self.dims = (0, 0, 0, 0, 0, 0, 0) elif isinstance(dims, str): self.dims = DimFloat.parse_dims(dims) else: self.dims = tuple(dims) if len(self.dims) != 7: raise ValueError("dims must be a 7-tuple for SI base units")
def __str__(self): dim_str = ' '.join(f"{u}^{p}" if p != 1 else f"{u}" for u, p in zip(SI_UNITS, self.dims) if p != 0) if not dim_str: dim_str = "dimensionless" return f"{self.value} ± {self.error} [{dim_str}]"
@staticmethod def parse_dims(dim_string): """ Parse a dimension string like 'm^3 kg^-1 s^-2' or 'm/s^2' into a tuple of powers for (m, kg, s, A, K, mol, cd). Supports multiplication by spaces, division by '/', powers with '^', and units without explicit powers (assumed 1). Example inputs: 'm^3 kg^-1 s^-2' 'kg' 'm/s^2' 'm2 kg-1' (some spaces or no spaces between power and unit not supported) """ # Initialize dimension powers to zero dims = [0] * 7
# Replace division with multiplication and negative powers: e.g. 'm/s^2' -> 'm s^-2' parts = dim_string.replace('/', ' / ').split() multiply_mode = True # True means next unit positive power, False means negative (division context)
# Regex to parse a unit with optional power: e.g. 'kg^2', 's^-3', 'm', 'A^1' unit_regex = re.compile(r'^([a-zA-Z]+)(\^([-+]?\d+))?$')
for part in parts: if part == '*': # Explicit multiplication, ignore as spaces also work as multiplication continue elif part == '/': multiply_mode = False continue
match = unit_regex.match(part) if not match: raise ValueError(f"Invalid dimension token: '{part}'")
unit, _, power_str = match.groups() power = int(power_str) if power_str else 1 power = power if multiply_mode else -power
# Map unit string to index if unit not in SI_UNITS: raise ValueError(f"Unknown SI unit symbol: '{unit}'") idx = SI_UNITS.index(unit) dims[idx] += power
return tuple(dims)
def _check_dims(self, other): if self.dims != other.dims: raise ValueError(f"Dimension mismatch: {self.dims} vs {other.dims}")
def __add__(self, other): if isinstance(other, DimFloat): self._check_dims(other) val = self.value + other.value # Errors add in quadrature err = sqrt(self.error**2 + other.error**2) return DimFloat(val, err, self.dims) return NotImplemented
def __sub__(self, other): if isinstance(other, DimFloat): self._check_dims(other) val = self.value - other.value err = sqrt(self.error**2 + other.error**2) return DimFloat(val, err, self.dims) return NotImplemented
def __mul__(self, other): if isinstance(other, DimFloat): val = self.value * other.value # Relative errors add in quadrature rel_err = sqrt( (self.error / self.value) ** 2 + (other.error / other.value) ** 2 ) if self.value and other.value else 0.0 dims = tuple(a + b for a, b in zip(self.dims, other.dims)) return DimFloat(val, abs(val) * rel_err, dims) elif isinstance(other, (float, int)): return DimFloat(self.value * other, abs(other) * self.error, self.dims) return NotImplemented
def __truediv__(self, other): if isinstance(other, DimFloat): val = self.value / other.value rel_err = sqrt( (self.error / self.value) ** 2 + (other.error / other.value) ** 2 ) if self.value and other.value else 0.0 dims = tuple(a - b for a, b in zip(self.dims, other.dims)) return DimFloat(val, abs(val) * rel_err, dims) elif isinstance(other, (float, int)): return DimFloat(self.value / other, self.error / abs(other), self.dims) return NotImplemented
def __pow__(self, power): if isinstance(power, (int, float)): val = self.value ** power rel_err = abs(power) * (self.error / self.value) if self.value else 0.0 dims = tuple(int(power * d) for d in self.dims) return DimFloat(val, abs(val) * rel_err, dims) return NotImplemented
def isclose(self, other, rel_tol=1e-9, abs_tol=0.0): if not isinstance(other, DimFloat): return False self._check_dims(other) return isclose(self.value, other.value, rel_tol=rel_tol, abs_tol=abs_tol)
# Example usages of parse_dims: if __name__ == "__main__": examples = [ "m^3 kg^-1", "kg", "m", "m/s^2", "m^2 s^-2", "kg m^2 / s^2", "m s / kg", ]
#for example in examples: # print(f"'{example}' => {DimFloat.parse_dims(example)}")
# Constants with values and uncertainties
# Gravitational constant G (CODATA 2018) G = DimFloat(6.67430e-11, 0.00015e-11, "m^3 kg^-1 s^-2")
# Mass of the Sun (CODATA with negligible uncertainty) M_sun = DimFloat(1.98847e30, 0.00001e30, "kg")
# Standard acceleration due to gravity g (exact by definition) g = DimFloat(9.80665, 0.0, "m s^-2")
# Distance Earth-Sun average in meters (93 million miles to meters) mile_to_meter = 1609.344 distance_miles = 93e6 r = DimFloat(distance_miles * mile_to_meter, 0.0, "m")
# Earth's radius for dimension calculation (not used explicitly in g/a) R_earth = DimFloat(6.371e6, 0.0, "m")
# Calculate acceleration due to Sun at distance r: a = G * M_sun / r^2 a = G * M_sun / (r ** 2) # m/s^2
# Calculate g/a ratio (dimensionless) g_div_a = g / a
print(f"G = {G}") print(f"Mass of Sun = {M_sun}") print(f"Distance to Sun (r) = {r}") print(f"Acceleration towards Sun at r (a) = {a}") print(f"Standard gravity on Earth (g) = {g}") print(f"Ratio g/a = {g_div_a}")