HOWTO · Python

Wie man eine Zahl in Python auf signifikante Stellen rundet

Lernen Sie, wie Sie Python-Zahlen mit round(), math, Formatierung, Decimal, sigfig und NumPy auf signifikante Stellen runden.

Auf dieser Seite

Um eine Zahl auf eine gewählte Anzahl signifikanter Stellen zu runden, bestimmen Sie ihre dezimale Größenordnung und übergeben die entsprechende Anzahl an Dezimalstellen an round(). So wird beispielsweise 1.342 auf eine signifikante Stelle gerundet zu 1.000. Für einen einzelnen Wert genügt die eingebaute Funktion; verwenden Sie eine Hilfsfunktion für wiederholte Berechnungen, Formatierung, wenn das Ergebnis als Text erhalten bleiben soll, Decimal, wenn dezimale Rundungsregeln wichtig sind, oder NumPy für Arrays.

Mit Python’s round() auf signifikante Stellen runden

round(number, ndigits) rundet auf eine Anzahl von Dezimalstellen. Für signifikante Stellen berechnen Sie ndigits als digits - 1 - floor(log10(abs(number))). Für 1.342 und eine signifikante Stelle ist dies 1 - 1 - 3, also -3, sodass Python auf das nächste Tausend rundet.

Führen Sie dieses Beispiel aus:

print(round(1342, -3))
1000

Python verwendet bei Fällen genau in der Mitte die Rundung zur geraden Zahl (ties-to-even), sodass die letzte beibehaltene Ziffer gerade ist, wenn der Wert genau in der Mitte zwischen zwei gerundeten Werten liegt. Dies unterscheidet sich davon, einen solchen Fall immer von null weg zu runden. Ein negatives ndigits rundet auf Zehner, Hunderter oder größere Zehnerpotenzen. round() gibt eine Zahl zurück; es bewahrt nachgestellte Nullen nicht als Darstellungsweise. Bei Gleitkommaeingaben kann auch die gespeicherte binäre Näherung scheinbare dezimale Fälle genau in der Mitte beeinflussen.

Mit einer math-Hilfsfunktion auf signifikante Stellen runden

Eine Hilfsfunktion kann die Anzahl der Dezimalstellen aus der Größenordnung zur Basis 10 berechnen. Die folgende Version akzeptiert positive ganzzahlige Stellenzahlen und endliche numerische Werte und gibt null unverändert zurück. Sie löst ValueError für eine nicht unterstützte Stellenzahl oder eine nicht endliche Eingabe aus, da log10() für diese Werte keine endliche dezimale Größenordnung bestimmen kann.

from math import floor, isfinite, log10


def round_significant(value, digits):
    if not isinstance(digits, int) or digits < 1:
        raise ValueError("digits must be a positive integer")
    if not isfinite(value):
        raise ValueError("value must be finite")
    if value == 0:
        return value
    places = digits - 1 - floor(log10(abs(value)))
    return round(value, places)


print(round_significant(1324, 2))

Die Formel funktioniert für positive und negative endliche Werte, weil sie abs(value) verwendet, um die Größenordnung zu finden, während round() das Vorzeichen bewahrt. Sie folgt Pythons Regel der Rundung zur geraden Zahl. Verwenden Sie math.isfinite(), um zu entscheiden, ob eine Eingabe unterstützt wird, bevor Sie den Logarithmus berechnen; behandeln Sie NaN und Unendlichkeiten separat, wenn Ihre Anwendung sie benötigt.

Mit Zeichenkettenformatierung auf signifikante Stellen runden

Das Format %g verwendet seine Präzision als Anzahl signifikanter Stellen. Bei Präzision p verwendet es die wissenschaftliche Schreibweise, wenn der dezimale Exponent kleiner als -4 oder größer als oder gleich p ist; andernfalls verwendet es die gewöhnliche Schreibweise. Bei Präzision 3 verwenden 0.0001 und 999 die gewöhnliche Schreibweise, während 0.00001 und 1000 die wissenschaftliche Schreibweise verwenden. Die Formatierung gibt eine Zeichenkette zurück, was nützlich ist, wenn das Ziel die Darstellung ist. Behalten Sie diese Zeichenkette, um ihre gewählte Darstellung zu bewahren; konvertieren Sie sie nur mit float(), wenn spätere numerische Operationen erforderlich sind. Das Konvertieren in eine Zahl verwirft Darstellungsdetails wie nachgestellte Nullen.

Beispielsweise formatiert "%.3g" % 1324 den Wert mit drei signifikanten Stellen. Das Ergebnis ist Text, und die genaue Wahl zwischen gewöhnlicher und wissenschaftlicher Schreibweise trifft der Formatierer.

Mit sigfig auf signifikante Stellen runden

Das Drittanbieterpaket sigfig akzeptiert die Anzahl signifikanter Stellen über sein Argument sigfigs. Installieren Sie das Paket in Ihrer Umgebung, bevor Sie es verwenden. Der Paketaufruf lautet beispielsweise sigfig.round(1324, sigfigs=2). Dies ist praktisch, wenn das Verhalten und die Formatierung des Pakets zu Ihrer Anwendung passen; für die oben beschriebenen eingebauten oder Hilfsansätze ist es nicht erforderlich.

Mit decimal.Decimal auf signifikante Stellen runden

Decimal unterstützt dezimale Arithmetik und einen expliziten Rundungsmodus. Konstruieren Sie es aus einer Zeichenkette, wenn die Dezimalziffern in der Eingabe wichtig sind; das Konvertieren eines vorhandenen Floats kann keine Informationen wiederherstellen, die der Float nicht gespeichert hat. Dieses Beispiel skaliert eine endliche Dezimalzahl ungleich null auf die gewünschte Präzision und rundet Fälle genau in der Mitte mit ROUND_HALF_UP von null weg.

from decimal import Decimal, ROUND_HALF_UP


def round_decimal_significant(value, digits):
    if not isinstance(digits, int) or digits < 1:
        raise ValueError("digits must be a positive integer")
    number = Decimal(str(value))
    if not number.is_finite():
        raise ValueError("value must be finite")
    if number.is_zero():
        return number
    quantum = Decimal(1).scaleb(number.adjusted() - digits + 1)
    return number.quantize(quantum, rounding=ROUND_HALF_UP)


print(round_decimal_significant("1324", 2))

Das Ergebnis bleibt ein Decimal. ROUND_HALF_UP ist nur eine Richtlinie; wählen Sie einen Modus wie ROUND_HALF_EVEN, wenn er zu den Regeln Ihrer Anwendung passt. Dezimale Arithmetik kann immer noch durch die aktive Kontextpräzision begrenzt sein, sodass sie keine unbegrenzte Präzision verspricht.

Arrays mit NumPy auf signifikante Stellen runden

NumPy ist nützlich, wenn die Eingabe ein Array ist, aber numpy.around() akzeptiert Dezimalstellen statt signifikanter Stellen. Berechnen Sie für einen endlichen Wert ungleich null die Anzahl der Dezimalstellen mit digits - 1 - floor(log10(abs(value))) und übergeben Sie sie an numpy.around(). Berechnen Sie die Größenordnungen für ein Array Element für Element und behandeln Sie Nullen und nicht endliche Werte, bevor Sie Logarithmen ziehen. NumPy ist eine zusätzliche Abhängigkeit; dieser Ansatz folgt dem Gleitkomma-Rundungsverhalten und bewahrt keine Darstellungsnullen.

Das folgende Beispiel rundet nur endliche Elemente ungleich null. Es lässt null, NaN sowie positives oder negatives Unendlich unverändert. Der zurückgegebene Wert ist ein NumPy-ndarray mit Gleitkommaelementen. NumPy ist eine zusätzliche Abhängigkeit, installieren Sie es also, bevor Sie dieses Beispiel ausführen.

import numpy as np


values = np.array([1234.5, -1234.5, 0.0, np.nan, np.inf, -np.inf])
digits = 3
rounded = values.copy()
finite_nonzero = np.isfinite(values) & (values != 0)

for index in np.flatnonzero(finite_nonzero):
    places = digits - 1 - int(np.floor(np.log10(abs(values[index]))))
    rounded[index] = np.around(values[index], decimals=places)

print(rounded.tolist())
[1230.0, -1230.0, 0.0, nan, inf, -inf]