Wie würde ich es schaffen, math.ceil
so zu arbeiten, dass eine Zahl der nächsthöheren Potenz von 10 zugewiesen wird?
# 0.04 -> 0.1
# 0.7 -> 1
# 1.1 -> 10
# 90 -> 100
# ...
Meine aktuelle Lösung ist ein Wörterbuch, das den Bereich der Eingabenummer überprüft, aber fest codiert ist, und ich würde eine einzeilige Lösung bevorzugen. Vielleicht fehlt mir hier ein einfacher mathematischer Trick oder eine entsprechende Numpy-Funktion?
10
oben funktionieren . Dies erfordert etwas mit zlog10
.Antworten:
Sie können
math.ceil
mit verwendenmath.log10
, um dies zu tun:log10(n)
gibt Ihnen die Lösungx
, die zufriedenstellend10 ** x == n
ist. Wenn Sie also aufrunden , erhaltenx
Sie den Exponenten für die nächsthöhere Potenz von 10.Beachten Sie, dass für einen Wert ,
n
wox
bereits eine ganze Zahl, die „nächsthöhere Leistung von 10“ wirdn
:quelle
10 ** math.ceil(math.log10(1)) == 1
was nicht "die nächsthöhere Potenz" istIhr Problem ist unterbestimmt. Sie müssen einen Schritt zurücktreten und einige Fragen stellen.
In einer anderen Antwort wurde vorgeschlagen, den Logarithmus zu nehmen, dann aufzurunden (Deckenfunktion) und dann zu potenzieren.
Leider weist dies Rundungsfehler auf. Zunächst wird n von einem beliebigen Datentyp in eine Gleitkommazahl mit doppelter Genauigkeit konvertiert, wodurch möglicherweise Rundungsfehler auftreten. Anschließend wird der Logarithmus berechnet, wodurch möglicherweise mehr Rundungsfehler sowohl in den internen Berechnungen als auch im Ergebnis auftreten.
Daher habe ich nicht lange gebraucht, um ein Beispiel zu finden, bei dem ein falsches Ergebnis erzielt wurde.
Es ist auch theoretisch möglich, dass es in die andere Richtung versagt, obwohl dies viel schwieriger zu provozieren scheint.
Für eine robuste Lösung für Floats und Ints müssen wir also davon ausgehen, dass der Wert unseres Logarithmus nur ungefähr ist, und wir müssen daher einige Möglichkeiten testen. Etwas in der Art von
Ich glaube, dieser Code sollte korrekte Ergebnisse für alle Argumente in einem vernünftigen realen Größenbereich liefern. Es wird für sehr kleine oder sehr große Anzahlen von nicht ganzzahligen und nicht Gleitkommatypen unterbrochen, da Probleme beim Konvertieren in Gleitkommatypen auftreten. Python-Sonderfälle Ganzzahlargumente für die Funktion log10, um einen Überlauf zu verhindern. Bei einer ausreichend massiven Ganzzahl können jedoch möglicherweise falsche Ergebnisse aufgrund von Rundungsfehlern erzwungen werden.
Um die beiden Implementierungen zu testen, habe ich das folgende Testprogramm verwendet.
Dies findet viele Fehler in der naiven Implementierung, aber keine in der verbesserten Implementierung.
quelle
round
stattmath.ceil
? Dies führt zu vielen unnötigen Fällen, in denen diesr < n
zutrifft, und erfordert daher zusätzliche Arbeiten.Es scheint, dass Sie eher die niedrigste nächste Potenz von 10 wollen ... Hier ist eine Möglichkeit, reine Mathematik und kein Protokoll, sondern Rekursion zu verwenden.
quelle
So etwas vielleicht? Es ist nur aus meinem Kopf, aber es hat funktioniert, als ich ein paar Nummern im Terminal ausprobiert habe.
quelle
Schau dir das an!
Dieser Code basiert auf dem Prinzip der Zehnermacht in
len( str( int( float_number ) ) )
.Es gibt 4 Fälle:
int( i ) > 1
.Float
Zahl - konvertiert inint
, danach Zeichenfolgestr()
daraus, gibt uns eine,string
mitlength
der wir genau suchen. Also, erster Teil, für die Eingabei > 1.0
- es ist zehn10
Potenzen dieser Länge.i > 1.0
undi > 0.1
<=> ist10
und1
jeweils.i < 0.1
: Hier sollen zehn in negativer Macht sein. Um das erste Nicht-Null-Element nach dem Komma zu erhalten, habe ich eine solche Konstruktion verwendet("%.100f" % i ).replace('.','').index( k )
, bei der k über das[1:10]
Intervall läuft . Nehmen Sie danach das Minimum der Ergebnisliste. Und um eins verringern, ist es die erste Null, die gezählt werden soll. Auch hier können Standard-Pythonsindex()
abstürzen, wenn sie nicht mindestens ein Nicht-Null-Element aus dem[1:10]
Intervall finden. Deshalb muss ich am Ende die Auflistung nach Vorkommen "filtern" :if str( j ) in "%.100f" % i
. Zusätzlich, um genauer zu werden -%.100f
kann anders genommen werden.quelle