Das Abschneiden von Floats in Python


110

Ich möchte Ziffern aus einem Float entfernen, um eine feste Anzahl von Ziffern nach dem Punkt zu erhalten, wie z.

1.923328437452 -> 1.923

Ich muss als Zeichenfolge für eine andere Funktion ausgeben, nicht drucken.

Außerdem möchte ich die verlorenen Ziffern ignorieren und nicht umrunden.


4
Sollte -1,233 auf -1,23 oder -1,24 abgeschnitten werden?
Antony Hatchkins

Antworten:


116

Erstens die Funktion für diejenigen, die nur Code zum Kopieren und Einfügen benötigen:

def truncate(f, n):
    '''Truncates/pads a float f to n decimal places without rounding'''
    s = '{}'.format(f)
    if 'e' in s or 'E' in s:
        return '{0:.{1}f}'.format(f, n)
    i, p, d = s.partition('.')
    return '.'.join([i, (d+'0'*n)[:n]])

Dies gilt in Python 2.7 und 3.1+. Bei älteren Versionen ist es nicht möglich, den gleichen "intelligenten Rundungseffekt" zu erzielen (zumindest nicht ohne viel komplizierten Code), aber das Runden auf 12 Dezimalstellen vor dem Abschneiden funktioniert meistens:

def truncate(f, n):
    '''Truncates/pads a float f to n decimal places without rounding'''
    s = '%.12f' % f
    i, p, d = s.partition('.')
    return '.'.join([i, (d+'0'*n)[:n]])

Erläuterung

Der Kern der zugrunde liegenden Methode besteht darin, den Wert mit voller Genauigkeit in eine Zeichenfolge umzuwandeln und dann einfach alles über die gewünschte Anzahl von Zeichen hinaus abzuschneiden. Der letzte Schritt ist einfach; Dies kann entweder mit String-Manipulation erfolgen

i, p, d = s.partition('.')
'.'.join([i, (d+'0'*n)[:n]])

oder das decimalModul

str(Decimal(s).quantize(Decimal((0, (1,), -n)), rounding=ROUND_DOWN))

Der erste Schritt, die Konvertierung in eine Zeichenfolge, ist ziemlich schwierig, da es einige Paare von Gleitkomma-Literalen gibt (dh was Sie im Quellcode schreiben), die beide dieselbe Binärdarstellung erzeugen und dennoch unterschiedlich abgeschnitten werden sollten. Betrachten Sie beispielsweise 0,3 und 0,29999999999999998. Wenn Sie 0.3in ein Python-Programm schreiben , codiert der Compiler es im IEEE-Gleitkommaformat in die Bitfolge (unter der Annahme eines 64-Bit-Gleitkommas).

0011111111010011001100110011001100110011001100110011001100110011

Dies ist der Wert, der 0,3 am nächsten kommt und genau als IEEE-Float dargestellt werden kann. Wenn Sie jedoch 0.29999999999999998in ein Python-Programm schreiben , übersetzt der Compiler es in genau denselben Wert . In einem Fall haben Sie gemeint, dass es abgeschnitten wird (auf eine Ziffer) 0.3, während Sie in dem anderen Fall gemeint haben, dass es abgeschnitten wird 0.2, aber Python kann nur eine Antwort geben. Dies ist eine grundlegende Einschränkung von Python oder einer anderen Programmiersprache ohne verzögerte Auswertung. Die Kürzungsfunktion hat nur Zugriff auf den im Speicher des Computers gespeicherten Binärwert, nicht auf die Zeichenfolge, die Sie tatsächlich in den Quellcode eingegeben haben. 1

Wenn Sie die Bitfolge wieder in eine Dezimalzahl dekodieren und erneut das IEEE 64-Bit-Gleitkommaformat verwenden, erhalten Sie

0.2999999999999999888977697537484345957637...

Eine naive Implementierung würde sich also einfallen lassen, 0.2obwohl Sie das wahrscheinlich nicht wollen. Weitere Informationen zum Gleitkomma-Darstellungsfehler finden Sie im Python-Lernprogramm .

Es ist sehr selten, mit einem Gleitkommawert zu arbeiten, der einer runden Zahl so nahe kommt und dennoch absichtlich nicht dieser runden Zahl entspricht. Wenn Sie also abschneiden, ist es wahrscheinlich sinnvoll, die "schönste" Dezimaldarstellung aus allen auszuwählen, die dem Wert im Speicher entsprechen könnten. Python 2.7 und höher (aber nicht 3.0) enthält einen ausgeklügelten Algorithmus , auf den wir über die Standardformatierungsoperation für Zeichenfolgen zugreifen können.

'{}'.format(f)

Die einzige Einschränkung besteht darin, dass dies wie eine Formatspezifikation wirkt g, in dem Sinne, dass die Exponentialnotation ( 1.23e+4) verwendet wird, wenn die Zahl groß oder klein genug ist. Die Methode muss diesen Fall also erfassen und anders behandeln. Es gibt einige Fälle, in denen die Verwendung einer fFormatspezifikation stattdessen ein Problem verursacht, z. B. der Versuch, die 3e-10Genauigkeit auf 28 Stellen abzuschneiden (dies führt zu 0.0000000002999999999999999980), und ich bin mir noch nicht sicher, wie ich mit diesen am besten umgehen soll.

Wenn Sie tatsächlich sind mit Arbeits floats , die sehr nah an runden Zahlen sind aber absichtlich gleich sie nicht (wie ,29999999999999998 oder 99,959999999999994), wird dies einige Fehlalarme produzieren, das heißt , es werden rund um Zahlen , dass Sie nicht gerundet haben wollten. In diesem Fall besteht die Lösung darin, eine feste Genauigkeit anzugeben.

'{0:.{1}f}'.format(f, sys.float_info.dig + n + 2)

Die Anzahl der hier zu verwendenden Genauigkeitsziffern spielt keine Rolle, sie muss nur groß genug sein, um sicherzustellen, dass bei der bei der Zeichenfolgenkonvertierung durchgeführten Rundung der Wert nicht auf seine schöne Dezimaldarstellung "erhöht" wird. Ich denke, es sys.float_info.dig + n + 2kann in allen Fällen ausreichen, aber wenn nicht, muss das 2möglicherweise erhöht werden, und es tut nicht weh, dies zu tun.

In früheren Versionen von Python (bis zu 2.6 oder 3.0) war die Formatierung von Gleitkommazahlen viel gröber und erzeugte regelmäßig Dinge wie

>>> 1.1
1.1000000000000001

Wenn dies Ihre Situation ist und Sie "schöne" Dezimaldarstellungen zum Abschneiden verwenden möchten, können Sie (soweit ich weiß) nur eine Anzahl von Ziffern auswählen, die unter der durch a darstellbaren vollen Genauigkeit liegen float, und die Zahl abrunden Nummerieren Sie diese Anzahl, bevor Sie sie abschneiden. Eine typische Wahl ist 12,

'%.12f' % f

Sie können dies jedoch an die von Ihnen verwendeten Zahlen anpassen.


1 Nun ... ich habe gelogen. Technisch Sie können Python anweisen , seinen eigenen Quellcode neu zu analysieren und den Teil , den Sie zum Abschneiden Funktion übergeben , um das erste Argument entspricht , zu extrahieren. Wenn dieses Argument ein Gleitkomma-Literal ist, können Sie es einfach um eine bestimmte Anzahl von Stellen nach dem Dezimalpunkt abschneiden und dieses zurückgeben. Diese Strategie funktioniert jedoch nicht, wenn das Argument eine Variable ist, was es ziemlich nutzlos macht. Folgendes wird nur zum Unterhaltungswert dargestellt:

def trunc_introspect(f, n):
    '''Truncates/pads the float f to n decimal places by looking at the caller's source code'''
    current_frame = None
    caller_frame = None
    s = inspect.stack()
    try:
        current_frame = s[0]
        caller_frame = s[1]
        gen = tokenize.tokenize(io.BytesIO(caller_frame[4][caller_frame[5]].encode('utf-8')).readline)
        for token_type, token_string, _, _, _ in gen:
            if token_type == tokenize.NAME and token_string == current_frame[3]:
                next(gen) # left parenthesis
                token_type, token_string, _, _, _ = next(gen) # float literal
                if token_type == tokenize.NUMBER:
                    try:
                        cut_point = token_string.index('.') + n + 1
                    except ValueError: # no decimal in string
                        return token_string + '.' + '0' * n
                    else:
                        if len(token_string) < cut_point:
                            token_string += '0' * (cut_point - len(token_string))
                        return token_string[:cut_point]
                else:
                    raise ValueError('Unable to find floating-point literal (this probably means you called {} with a variable)'.format(current_frame[3]))
                break
    finally:
        del s, current_frame, caller_frame

Dies zu verallgemeinern, um den Fall zu behandeln, in dem Sie eine Variable übergeben, scheint eine verlorene Ursache zu sein, da Sie die Programmausführung rückwärts verfolgen müssten, bis Sie das Gleitkomma-Literal finden, das der Variablen ihren Wert gegeben hat. Wenn es überhaupt einen gibt. Die meisten Variablen werden aus Benutzereingaben oder mathematischen Ausdrücken initialisiert. In diesem Fall ist nur die binäre Darstellung vorhanden.


Wie können wir diese Funktion auf einen Datenrahmen anwenden?
Codeslord

@RohithRNair Auf die gleiche Weise, wie Sie jede andere Funktion anwenden würden, die auf einzelne Elemente (dh applymap()) angewendet wird . Vielleicht gibt es eine Möglichkeit, den gesamten Vorgang effizienter zu gestalten, aber das wäre eine Frage einer separaten Frage.
David Z

applymap () nimmt viel Zeit in Anspruch, da meine Datenrahmen sehr groß sind. Ich versuche, zwei Datenrahmen auf Unterschiede zu vergleichen, aber die Gleitkommapräzision verzerrt meine Ausgabe vom gewünschten Wert. Wie Sie sagten, werde ich eine separate Frage dazu stellen. Vielen Dank.
Codeslord

@RohithRNair Ah, wenn Sie versuchen, zwei Datenrahmen auf Unterschiede zu vergleichen, fragen Sie stattdessen danach. Das Abschneiden der Werte (worum es in dieser Frage geht) ist nicht der beste Weg, dies zu tun.
David Z

Nur eine Anmerkung, Ihr Code scheint negative Zahlen auf negative Null zu zerhacken, was verwirrend werden kann ...
user541686

152
round(1.923328437452, 3)

Weitere Informationen zu den Standardtypen finden Sie in der Python-Dokumentation . Sie müssen ein wenig nach unten scrollen, um zur Rundungsfunktion zu gelangen. Im Wesentlichen gibt die zweite Zahl an, auf wie viele Dezimalstellen gerundet werden soll.


49
Ich meinte, Rundung ist nicht das, was ich brauche. Ich muss abschneiden, was anders ist.
Joan Venge

1
Ahhh, fair genug. Mein Fehler tut mir leid.
Teifion

22
Das sind viele positive Stimmen für eine falsche Lösung! Eine dieser seltsamen Stackoverflow-Raritäten. Ich frage mich, ob es ein Abzeichen dafür gibt ...
tumultous_rooster

5
Es ist nur entsetzlich, wie viele falsche Antworten (und positive Stimmen für die falschen Antworten) es für diese Frage gibt.
nullstellensatz

6
Viele Leute werden auf diese Seite kommen und nach Rundungen suchen;)
janjackson

33

Das Ergebnis von roundist ein Float. Achten Sie also darauf (Beispiel stammt aus Python 2.6):

>>> round(1.923328437452, 3)
1.923
>>> round(1.23456, 3)
1.2350000000000001

Wenn Sie eine formatierte Zeichenfolge verwenden, sind Sie besser dran:

>>> "%.3f" % 1.923328437452
'1.923'
>>> "%.3f" % 1.23456
'1.235'

8
Auf meinem Python rundet das: '% .3f'% 1.23456 == '1.235'
David Z

Dies ist viel eleganter als der manuelle String-Formatierungs-Unsinn, guter Beitrag!
Rsethc

round(1.23456, 3)ist 1.235und nicht1.2350000000000001
Ahmad

1
@ Ahmad nicht unbedingt. Das Beispiel hier stammt aus Python 2.6 (beachten Sie das Datum der Antwort). Die Zeichenfolgenformatierung wurde in Python 2.7 / 3.1 verbessert. Deshalb erhalten Sie wahrscheinlich unterschiedliche Ergebnisse. Trotzdem haben Gleitkommazahlen häufig unerwartete Zeichenfolgendarstellungen, siehe: docs.python.org/3.6/tutorial/floatingpoint.html
Ferdinand Beyer

21
n = 1.923328437452
str(n)[:4]

3
Einfach und pythonisch. 4 ist jedoch die Größe der ganzen Zahl, nicht nur die Ziffern nach dem Punkt.
GaTTaCa

4
Wenn der Benutzer beispielsweise eingibt 2, wird .am Ende der Zeichenfolge ein Dezimalpunkt angezeigt - meiner Meinung nach keine wirklich gute Lösung.
Zelphir Kaltstahl

Dies ist spezifisch für einen Fall dieser Nummer. Wie würde es auf 11.923328437452 verallgemeinern?
polarisieren

Beste Antwort! Sie können auch float () hinzufügen, um eine Zahl zurückzugeben: float (str (n) [: 4])
justSaid

14

An meiner Python 2.7-Eingabeaufforderung:

>>> int(1.923328437452 * 1000)/1000.0 1.923


11

Einfaches Python-Skript -

n = 1.923328437452
n = float(int(n * 1000))
n /=1000

3
Saubere Antwort. Sie verpassen nur einen Schritt, um vor dem Teilen durch 1000 wieder in Float umzuwandeln. Andernfalls erhalten Sie 1.
Yohan Obadia

9
def trunc(num, digits):
   sp = str(num).split('.')
   return '.'.join([sp[0], sp[1][:digits]])

Das sollte funktionieren. Es sollte Ihnen die Kürzung geben, die Sie suchen.


9

Die wirklich pythonische Art, es zu tun, ist

from decimal import *

with localcontext() as ctx:
    ctx.rounding = ROUND_DOWN
    print Decimal('1.923328437452').quantize(Decimal('0.001'))

oder kürzer:

from decimal import Decimal as D, ROUND_DOWN

D('1.923328437452').quantize(D('0.001'), rounding=ROUND_DOWN)

Aktualisieren

Normalerweise liegt das Problem nicht darin, Floats selbst abzuschneiden, sondern darin, Float-Zahlen vor dem Runden falsch zu verwenden .

Beispielsweise: int(0.7*3*100)/100 == 2.09 .

Wenn Sie gezwungen sind , Floats zu verwenden (z. B. beschleunigen Sie Ihren Code mit numba), ist es besser, Cent als "interne Darstellung" der Preise zu verwenden: ( 70*3 == 210) und die Ein- / Ausgänge zu multiplizieren / zu dividieren.


Parson mich dafür, dass ich das gefragt habe, aber ... warum?
Markroxor

@markroxor, nicht sicher, worüber Sie genau fragen. Als Nebenbemerkung liegt das Problem normalerweise nicht in der Rundung selbst, sondern in der unsachgemäßen Verwendung von Gleitkommazahlen vor der Rundung. ZB int(0.7*3*100)/100 == 2.09. Wo ist mein 1 Cent geblieben?
Antony Hatchkins

Das macht Sinn. Können Sie Ihre Antwort mit dieser Erklärung bearbeiten? Vielen Dank.
Markroxor

Erhalten ImportError: cannot import name 'D', ich glaube, Sie wollten eine benannte Import-Nr. Machen?
Overdrivr

8

So viele der Antworten auf diese Frage sind einfach völlig falsch. Sie runden entweder Floats auf (anstatt sie abzuschneiden) oder funktionieren nicht in allen Fällen.

Dies ist das beste Google-Ergebnis, wenn ich nach "Python truncate float" suche, einem Konzept, das wirklich einfach ist und bessere Antworten verdient. Ich stimme Hatchkins zu, dass die Verwendung derdecimal Moduls die pythonische Methode ist, daher gebe ich hier eine Funktion, die meiner Meinung nach die Frage richtig beantwortet und in allen Fällen wie erwartet funktioniert.

Als Randnotiz können Bruchwerte im Allgemeinen nicht genau durch binäre Gleitkommavariablen dargestellt werden (siehe hier für eine Diskussion darüber), weshalb meine Funktion einen String zurückgibt.

from decimal import Decimal, localcontext, ROUND_DOWN

def truncate(number, places):
    if not isinstance(places, int):
        raise ValueError("Decimal places must be an integer.")
    if places < 1:
        raise ValueError("Decimal places must be at least 1.")
    # If you want to truncate to 0 decimal places, just do int(number).

    with localcontext() as context:
        context.rounding = ROUND_DOWN
        exponent = Decimal(str(10 ** - places))
        return Decimal(str(number)).quantize(exponent).to_eng_string()

4

Ich habe so etwas gemacht:

from math import trunc


def truncate(number, decimals=0):
    if decimals < 0:
        raise ValueError('truncate received an invalid value of decimals ({})'.format(decimals))
    elif decimals == 0:
        return trunc(number)
    else:
        factor = float(10**decimals)
        return trunc(number*factor)/factor

4

Du kannst tun:

def truncate(f, n):
    return math.floor(f * 10 ** n) / 10 ** n

testen:

>>> f=1.923328437452
>>> [truncate(f, n) for n in range(5)]
[1.0, 1.9, 1.92, 1.923, 1.9233]

Dies wird nur mit positiven Zahlen abgeschnitten, negative Zahlen werden abgerundet (von Null weg).
Aaron D

3

Wenn Sie sich für Mathematik interessieren, funktioniert dies für + ve Zahlen:

>>> v = 1.923328437452
>>> v - v % 1e-3
1.923

Soweit ich weiß, wird 1e-3 nach dem Punkt auf 3 Stellen abgeschnitten. Ich mochte diese Antwort, aber es scheint nicht für 4 und 5 zu funktionieren.
egvo

2

Bei der Verwendung eines Pandas df hat dies bei mir funktioniert

import math
def truncate(number, digits) -> float:
    stepper = 10.0 ** digits
    return math.trunc(stepper * number) / stepper

df['trunc'] = df['float_val'].apply(lambda x: truncate(x,1))
df['trunc']=df['trunc'].map('{:.1f}'.format)

1

Ich wollte nur erwähnen, dass der alte Trick "make round () with floor ()" von

round(f) = floor(f+0.5)

kann gedreht werden, um floor () aus round () zu machen

floor(f) = round(f-0.5)

Obwohl diese beiden Regeln um negative Zahlen herum brechen, ist ihre Verwendung nicht ideal:

def trunc(f, n):
    if f > 0:
        return "%.*f" % (n, (f - 0.5*10**-n))
    elif f == 0:
        return "%.*f" % (n, f)
    elif f < 0:
        return "%.*f" % (n, (f + 0.5*10**-n))

1

int (16,5); Dies ergibt einen ganzzahligen Wert von 16, dh Trunc, kann keine Dezimalstellen angeben, aber Sie können dies mit tun

import math;

def trunc(invalue, digits):
    return int(invalue*math.pow(10,digits))/math.pow(10,digits);

1

Hier ist ein einfacher Weg:

def truncate(num, res=3):
    return (floor(num*pow(10, res)+0.5))/pow(10, res)

für num = 1.923328437452 gibt dies 1.923 aus



1

Eine allgemeine und einfache Funktion:

def truncate_float(number, length):
    """Truncate float numbers, up to the number specified
    in length that must be an integer"""

    number = number * pow(10, length)
    number = int(number)
    number = float(number)
    number /= pow(10, length)
    return number

Toll! Die Umwandlung in int schneidet sowohl positive als auch negative Zahlen ab.
Aaron D

1

In Python 3 gibt es eine einfache Problemumgehung. Wo geschnitten werden soll Ich habe mit einer Hilfevariablen decPlace definiert, um die Anpassung zu vereinfachen.

f = 1.12345
decPlace= 4
f_cut = int(f * 10**decPlace) /10**decPlace

Ausgabe:

f = 1.1234

Ich hoffe es hilft.


1
def precision(value, precision):
    """
    param: value: takes a float
    param: precision: int, number of decimal places
    returns a float
    """
    x = 10.0**precision
    num = int(value * x)/ x
    return num
precision(1.923328437452, 3)

1,923


Schön, aber Sie runden nicht.
Alex

1

Kurze und einfache Variante

def truncate_float(value, digits_after_point=2):
    pow_10 = 10 ** digits_after_point
    return (float(int(value * pow_10))) / pow_10

>>> truncate_float(1.14333, 2)
>>> 1.14

>>> truncate_float(1.14777, 2)
>>> 1.14


>>> truncate_float(1.14777, 4)
>>> 1.1477

1

Die meisten Antworten sind meiner Meinung nach viel zu kompliziert. Wie wäre es damit?

digits = 2  # Specify how many digits you want

fnum = '122.485221'
truncated_float = float(fnum[:fnum.find('.') + digits + 1])

>>> 122.48

Scannen Sie einfach nach dem Index von '.' und wie gewünscht abschneiden (keine Rundung). Konvertieren Sie den String als letzten Schritt in Float.

Oder in Ihrem Fall, wenn Sie einen Float als Eingabe erhalten und einen String als Ausgabe möchten:

fnum = str(122.485221)  # convert float to string first
truncated_float = fnum[:fnum.find('.') + digits + 1]  # string output

Ihr Vorschlag ist problematisch, wenn die Zahl, die abgeschnitten wird, klein ist, da Sie viel Präzision mit der führenden 0 rechts vom Dezimalpunkt verschwenden würden. Dieses Problem ist jedoch wie angegeben endemisch für das Problem. Ich versuche zu sagen, dass signifikante Zahlen die wahre Antwort sind.
Überrollung

1
>>> floor((1.23658945) * 10**4) / 10**4
1.2365

# dividieren und multiplizieren Sie mit 10 ** Anzahl der gewünschten Ziffern


0

benutze numpy.round

import numpy as np
precision = 3
floats = [1.123123123, 2.321321321321]
new_float = np.round(floats, precision)

0

Etwas, das einfach genug ist, um in ein Listenverständnis zu passen, ohne Bibliotheken oder andere externe Abhängigkeiten. Für Python> = 3.6 ist es sehr einfach, mit F-Strings zu schreiben.

Die Idee ist, die String-Konvertierung die Rundung auf eine Stelle mehr als nötig durchführen zu lassen und dann die letzte Ziffer abzuschneiden.

>>> nout = 3  # desired number of digits in output
>>> [f'{x:.{nout+1}f}'[:-1] for x in [2/3, 4/5, 8/9, 9/8, 5/4, 3/2]]
['0.666', '0.800', '0.888', '1.125', '1.250', '1.500']

Natürlich findet hier eine Rundung statt (nämlich für die vierte Ziffer), aber irgendwann ist eine Rundung unvermeidlich. Für den Fall, dass der Übergang zwischen Abschneiden und Runden relevant ist, hier ein etwas besseres Beispiel:

>>> nacc = 6  # desired accuracy (maximum 15!)
>>> nout = 3  # desired number of digits in output
>>> [f'{x:.{nacc}f}'[:-(nacc-nout)] for x in [2.9999, 2.99999, 2.999999, 2.9999999]]
>>> ['2.999', '2.999', '2.999', '3.000']

Bonus: Nullen rechts entfernen

>>> nout = 3  # desired number of digits in output
>>> [f'{x:.{nout+1}f}'[:-1].rstrip('0') for x in [2/3, 4/5, 8/9, 9/8, 5/4, 3/2]]
['0.666', '0.8', '0.888', '1.125', '1.25', '1.5']

0

Die hier gegebene Kernidee scheint mir der beste Ansatz für dieses Problem zu sein. Leider hat es weniger Stimmen erhalten, während die spätere Antwort mit mehr Stimmen nicht vollständig ist (wie in den Kommentaren angegeben). Hoffentlich bietet die folgende Implementierung eine kurze und vollständige Lösung für das Abschneiden .

def trunc(num, digits):
    l = str(float(num)).split('.')
    digits = min(len(l[1]), digits)
    return (l[0]+'.'+l[1][:digits])

die sich um alle hier und hier gefundenen Eckfälle kümmern sollte .


-1

Ich bin auch ein Python-Neuling und nachdem ich hier ein paar Kleinigkeiten verwendet habe, biete ich meine zwei Cent an

print str(int(time.time()))+str(datetime.now().microsecond)[:3]

str (int (time.time ())) nimmt die Zeitepoche als int und konvertiert sie in einen String und verbindet sich mit ... str (datetime.now (). microsecond) [: 3], das nur die Mikrosekunden zurückgibt, convert auf die ersten 3 Zeichen setzen und abschneiden


-1
# value  value to be truncated
# n  number of values after decimal

value = 0.999782
n = 3
float(int(value*1en))*1e-n

-3

Wenn Sie beim Drucken meinen, sollte Folgendes funktionieren:

print '%.3f' % number

2
Das rundet die Zahl ab, es wird nicht abgeschnitten.
David Z
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.