Wie können Sie eine beliebige Zahl (nicht nur ganze Zahlen> 0) auf N signifikante Stellen runden ?
Wenn ich beispielsweise auf drei signifikante Stellen runden möchte, suche ich nach einer Formel, die Folgendes annehmen könnte:
1.239.451 und geben 1.240.000 zurück
12.1257 und zurück 12.1
.0681 und zurück .0681
5 und zurück 5
Natürlich sollte der Algorithmus nicht fest codiert sein, um nur N von 3 zu handhaben, obwohl dies ein Anfang wäre.
Antworten:
Hier ist der gleiche Code in Java ohne den 12.100000000000001-Fehler, den andere Antworten haben
Ich habe auch wiederholten Code entfernt,
power
in eine Ganzzahl geändert , um schwebende Probleme zu vermeiden, wennn - d
dies erledigt ist, und das lange Zwischenprodukt klarer gemachtDer Fehler wurde durch Multiplizieren einer großen Zahl mit einer kleinen Zahl verursacht. Stattdessen teile ich zwei Zahlen ähnlicher Größe.
BEARBEITEN
Weitere Fehler behoben. Überprüfung für 0 hinzugefügt, da dies zu NaN führen würde. Die Funktion funktioniert tatsächlich mit negativen Zahlen (Der ursprüngliche Code behandelt keine negativen Zahlen, da ein Protokoll einer negativen Zahl eine komplexe Zahl ist.)
quelle
Hier ist eine kurze und süße JavaScript-Implementierung:
quelle
n==0
:)Math.log(n) / Math.LN10
und nichtMath.log10(n)
?Math.floor(x) == Math.ceil(x) - 1
? Weil es nicht ist, wennx
es eine ganze Zahl ist. Ich denke, das zweite Argument derpow
Funktion sollte seinsig - Math.ceil(Math.log(n) / Math.LN10)
(oder nur verwendenMath.log10
)ZUSAMMENFASSUNG:
Sie müssen also die Dezimalstelle der ersten Ziffer ungleich Null ermitteln, dann die nächsten N-1-Ziffern speichern und dann die N-te Ziffer basierend auf dem Rest runden.
Wir können log verwenden, um das erste zu tun.
Nehmen Sie für Zahlen> 0 die Obergrenze des Protokolls. Nehmen Sie für Zahlen <0 das Wort des Protokolls.
Jetzt haben wir die Ziffer
d
: 7 im ersten Fall, 2 im 2., -2 im 3 ..Wir müssen die
(d-N)
dritte Ziffer runden . Etwas wie:Dann machen Sie die Standardrundung:
Und mache den Powder rückgängig.
Wobei Leistung die oben berechnete Leistung ist.
Über Genauigkeit: Die Antwort von Pyrolistical ist in der Tat näher am tatsächlichen Ergebnis. Beachten Sie jedoch, dass Sie 12.1 auf keinen Fall genau darstellen können. Wenn Sie die Antworten wie folgt drucken:
Die Antworten sind:
Verwenden Sie also Pyros Antwort!
quelle
Ist nicht die "kurze und süße" JavaScript-Implementierung
z.B
?
Entschuldigung, ich bin hier nicht scherzhaft, es ist nur so, dass die Verwendung der "roundit" -Funktion von Claudiu und der .toPrecision in JavaScript zu unterschiedlichen Ergebnissen führt, jedoch nur bei der Rundung der letzten Ziffer.
JavaScript:
.NETZ
quelle
Number(814301).toPrecision(4) == "8.143e+5"
. Im Allgemeinen nicht das, was Sie wollen, wenn Sie dies Benutzern zeigen.Die (sehr schöne!) Lösung von Pyrolistical hat immer noch ein Problem. Der maximale Doppelwert in Java liegt in der Größenordnung von 10 ^ 308, während der minimale Wert in der Größenordnung von 10 ^ -324 liegt. Daher können Probleme auftreten, wenn Sie die Funktion
roundToSignificantFigures
auf etwas anwenden , das innerhalb weniger Zehnerpotenzen liegtDouble.MIN_VALUE
. Zum Beispiel, wenn Sie anrufendann wird die Variable
power
wird den Wert 3 - (-309) = 312. Folglich wird der Variablemagnitude
wird wordenInfinity
, und es ist alles Müll von da an aus. Glücklicherweise ist dies kein unüberwindbares Problem: Es ist nur der Faktormagnitude
, der überläuft. Was wirklich zählt, ist das Produktnum * magnitude
, und das läuft nicht über. Eine Möglichkeit, dies zu beheben, besteht darin, die Multiplikation mit dem Faktormagintude
in zwei Schritte aufzuteilen:quelle
Wie wäre es mit dieser Java-Lösung:
quelle
Hier ist eine modifizierte Version von Ates 'JavaScript, die negative Zahlen verarbeitet.
quelle
Dies kam 5 Jahre zu spät, aber obwohl ich für andere teilen werde, die immer noch das gleiche Problem haben. Ich mag es, weil es einfach ist und keine Berechnungen auf der Codeseite. Weitere Informationen finden Sie unter Integrierte Methoden zum Anzeigen wichtiger Zahlen .
Dies ist, wenn Sie es nur ausdrucken möchten.
Dies ist, wenn Sie es konvertieren möchten:
Hier ist ein Beispiel dafür in Aktion:
quelle
JavaScript:
Die
Number
Funktion ändert die Ausgabe des Formulars"8.143e+5"
in"814300"
.quelle
Haben Sie versucht, es so zu codieren, wie Sie es von Hand tun würden?
quelle
[Korrigiert am 26.10.2009]
Im Wesentlichen für N signifikante gebrochene Zahlen:
• Multiplizieren Sie die Zahl mit 10 N
• Addieren Sie 0,5
• Schneiden Sie die Bruchziffern ab (dh schneiden Sie das Ergebnis in eine ganze Zahl ab)
• Teilen Sie durch 10 N.
Für N signifikante ganzzahlige (nicht gebrochene) Ziffern:
• Teilen Sie die Zahl durch 10 N
• Addieren Sie 0,5
• Schneiden Sie die Bruchziffern ab (dh schneiden Sie das Ergebnis in eine ganze Zahl ab)
• Multiplizieren Sie mit 10 N.
Sie können dies beispielsweise auf jedem Taschenrechner tun, der über einen Operator "INT" (Integer Truncation) verfügt.
quelle
quelle
Hier ist der Code von Pyrolistical (derzeit die beste Antwort) in Visual Basic.NET, falls jemand ihn benötigt:
quelle
Dies ist eine, die ich mir in VB ausgedacht habe:
quelle
return new BigDecimal(value, new MathContext(significantFigures, RoundingMode.HALF_UP)).doubleValue();
quelle
Ich brauchte dies in Go, was durch das Fehlen der Go-Standardbibliothek
math.Round()
(vor go1.10) etwas kompliziert wurde . Also musste ich das auch aufpeitschen. Hier ist meine Übersetzung der ausgezeichneten Antwort von Pyrolistical :quelle
Sie können alle diese Berechnungen mit Potenzen von 10 usw. vermeiden, indem Sie einfach FloatToStrF verwenden.
Mit FloatToStrF können Sie (unter anderem) die Genauigkeit (Anzahl der signifikanten Ziffern) des ausgegebenen Werts (der eine Zeichenfolge sein wird) auswählen. Natürlich können Sie dann StrToFloat darauf anwenden, um Ihren gerundeten Wert als Float zu erhalten.
Siehe hier:
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/SysUtils_FloatToStrF@Extended@TFloatFormat@[email protected]
quelle
Dieser Code verwendet die integrierte Formatierungsfunktion, die in eine Rundungsfunktion umgewandelt wird
quelle