Zufriedenstellende Rundung
Sie wissen, wann Sie im Naturwissenschaftsunterricht sind, und haben gebeten, auf 2 Sig Feigen zu runden, aber Ihre Antwort lautet 5.2501...
? Sie sollten sich zu runden 5.3
, aber das ist einfach so unbefriedigend! Wenn Sie auf runden 5.3
, haben Sie eine ganze Differenz von 0,05, was im Vergleich zu 0,1 (dem Stellenwert, auf den Sie runden) eine große Abweichung darstellt! Also hilf mir auf befriedigende Weise.
Um zufriedenstellend zu runden, müssen Sie an der ersten Stelle runden, die einen relativ kleinen Fehler verursacht - weniger als die Hälfte des maximal möglichen Rundungsfehlers. Grundsätzlich müssen Sie immer dann runden, wenn Sie auf 0, 1, 8 oder 9 stoßen. Wenn dies nicht der Fall ist, geben Sie die Eingabe wie sie ist zurück. Runden Sie nicht auf führende Nullen oder Einsen - das fühlt sich einfach nicht befriedigend an.
Eingang
Ein String oder Float-Wert, der eine nicht negative Dezimalzahl darstellt.
Ausgabe
Dieselbe Dezimalzahl wurde zufriedenstellend gerundet, entweder im Zeichenfolgen- oder im Gleitkommaformat.
Beispiele
Input -> Output
0 -> 0
0.5 -> 0.5
0.19 -> 0
0.8 -> 1
5.64511 -> 5.645
18.913 -> 20
88.913 -> 100
36.38299 -> 36.4
621 -> 620
803.22 -> 1000
547.4726 -> 547.4726
Dies ist eine Code-Golf- Herausforderung, also gewinnt der kürzeste Code!
quelle
036.40000
eine gültige Ausgabe?.0
Teil für ganze Zahlen angegeben wird? Auch0
ist nicht positiv.19
rundet auf20
aber0.19
rundet auf0
? Warum?Antworten:
JavaScript (ES6),
100 99 9878 ByteÜbernimmt die Eingabe als Zeichenfolge. Gibt ein float zurück.
Probieren Sie es online!
Wie?
Wir stellen der Eingabezeichenfolge zuerst eine führende0 voran , damit wir garantiert eine Ziffer vor einer möglichen führenden 8 oder 9 haben, die die Rundung sofort auslösen muss.
Das Flagj wird auf 1 gesetzt, solange wir nach einer Ziffer suchen, auf die wir eine zufriedenstellende Rundung durchführen können, und anschließend auf 0 .
Da der Zeichenfolge, durch die wir gehen, eine führende0 hinzugefügt wurde, s jedoch unverändert blieb, enthält d das aktuelle Zeichen und s [ i ] zeigt auf das nächste Zeichen.
Wir verwenden den folgenden Code, um die nächste Ziffer inn zu laden , wobei ein mögliches Dezimaltrennzeichen übersprungen wird:
Obwohl Strings in JavaScript unveränderlich ist, der Ausdrucks [ i ] + 1 , wenn es einen numerischen Wert enthält, auch wenn s [ i ] nicht tatsächlich erhöht. Daher wird der Ausdruck fa l s e (dazu gezwungen zu 0 ) für alle Ziffern (einschließlich 0 ) und t r u e (dazu gezwungen zu 1 ) für das Dezimalzeichen
++s[i]
kehrt!++s[i]
ausgewertet wird, um"."
.Wenn die Rundungs auftreten, ergeben wir ,n ist 0 oder 1 (und es ist nicht die führende Ziffer des ursprünglichen Eingangs) und n ist 8 oder 9 . Deshalb,j 0 0 d 1
d + --j
wenn die nächste Zahld + j--
wennquelle
Ruby ,
7977696765 BytesProbieren Sie es online!
Erläuterung
->n
Eingabe als String übernehmenz=n+".0"
Erstellen Sie eine temporäre Zeichenfolgez
, die garantiert einen Punkt und eine relevante Ziffer enthält.i=z=~/\./
Bestimmen Sie die Position des Dezimalpunkts inz
und weisen Sie zui
.z[i]=''
Lass den Punkt fallen, damit er dich nicht weiter stört.z=~/(?!^)[01]|8|9/
Bestimmen Sie die Position des Nichtstarters0-1
oder eines anderen8-9
, je nachdem, was zuerst eintritt.(...)-i
Diese Differenz ist die Anzahl der zu erhaltenden Dezimalstellen, negativ, wenn wir links vom Punkt abrunden.n.to_f.round ...
In Float umwandeln und runden.quelle
Jelly , 34 Bytes
Probieren Sie es online!
-1 Danke an Jonathan Allan .
quelle
ŒV
? Ich denke,V
wird auch funktionieren._>¥0ɓVær
wie meine ist (ich habe die Verwendung der dyadischen schnell verpasst, also danke auch!)Gelee ,
3029 Bytes-1 danke an Erik den Outgolfer (Verwendung von dyadic schnell
¥
aus seiner Antwort)Ein monadischer Link, der eine Liste von Zeichen akzeptiert, die ein Float ergibt.
Probieren Sie es online! Oder schauen Sie sich die Testsuite an .
Wie
Beachten Sie zunächst, dass die Eingabezeichenfolge ausschließlich aus den Zeichen besteht
0123456789.
, die Ordnungszahlen haben[48,49,50,51,52,53,54,55,56,57,46]
, die Restzeichen enthalten , wenn sie durch acht von geteilt werden[0,1,2,3,4,5,6,7,0,1,6]
. Die einzigen Zeichen , die zwischen sind-1
und1
sind inklusive0
,1
,8
, und9
.Wenn wir außerdem acht von den Ordnungszahlen (
[40,41,42,43,44,45,46,47,48,49,38]
) abziehen, gilt dasselbe (ziemlich offensichtlich). Wenn wir diese ([20,20.5,21,21.5,22,22.5,23,23.5,24,24.5,19]
) halbieren, sind und die einzigen Zeichen, die bei Division durch acht Restzeichen haben, die zwischen-1
und1
einschließlich liegen .8
9
quelle
Retina 0.8.2 , 75 Bytes
Probieren Sie es online! Link enthält Testfälle. Erläuterung:
Behandeln Sie den Fall eines führenden
8
oder9
.Wenn es ein nicht führendes
0
oder gibt1
, dann nullen Sie es und den Rest der Zeichenfolge aus. Auch wenn es ein8
oder gibt9
, lassen Sie es, aber setzen Sie den Rest der Zeichenfolge auf Null. (Lassen Sie den Dezimalpunkt jedoch in beiden Fällen unverändert.)Wenn zu diesem Zeitpunkt noch ein
8
oder ein vorhanden9
ist, setzen Sie es auf Null und erhöhen Sie die vorherige Ziffer (möglicherweise vor dem Dezimalpunkt).Löschen Sie nachfolgende Nullen, wenn sie nach einem Dezimalpunkt liegen, aber löschen Sie den Dezimalpunkt nur, wenn keine anderen Ziffern dazwischen stehen.
quelle
C (GCC) ,
111102 BytesProbieren Sie es online!
quelle
C # (Visual C # Interactive Compiler) , 280 Byte
Probieren Sie es online!
Es kann kürzer sein, wenn ich Doppelte anstelle von Dezimalstellen verwendet habe, aber ich habe Dezimalstellen verwendet, um die Genauigkeit zu erhalten, oder eine Zahl wie 547.4726 wäre 547.472595214844.
C # (Visual C # Interactive Compiler) , 268 Byte
Probieren Sie es online aus! (Weniger genaue Version)
quelle