2016-07-06 10 views
2

Ich möchte eine Funktion haben digits :: Double -> Int -> Double, die n Ziffern eines Doppel gibt (müssen rund!) Und gibt ein neues Doppel nur mit den gewünschten Ziffern.Wie bekomme ich n Ziffern eines Haskell Double?

Beispiel: digits 1.2345 3 -> 1.235

Ich konnte dies mit Strings implementieren, aber ich denke, dass es eine bessere Lösung ist. Haben Sie eine Idee, wie Sie diese Funktion implementieren?

Vielen Dank im Voraus!

+7

Denken Sie daran, dass 'Double' eine * binäre * Fließkommazahl ist und nie genau '1,235' darstellen kann (der richtige Bruchteil hat keine Zweierpotenz als Nenner). Das heißt, das riecht nach einem X/Y-Problem. Wenn Sie diese Rundung für die Präsentation durchführen, sind Strings wirklich die bessere Option. Wenn Sie genaue Dezimalberechnungen benötigen (in einer verwandten Anmerkung: * Verwenden Sie niemals Gleitkommazahlen für Währungen *), ist es vielleicht eine bessere Idee, Festkommaberechnungen zu verwenden (mit 'Ganzzahlen unter der Haube statt 'Doppel'). Was die "bessere Lösung" ist, hängt davon ab, warum Sie dies tun wollen. –

+0

Hinweis: 10^3 == 1000 –

Antwort

3

Ein relativ einfacher Weg ist es, mit einer geeigneten Zehnerpotenz zu multiplizieren und dann die Zehnerpotenz wegzuteilen. Zum Beispiel:

digits d n = fromInteger (round (d * 10^n))/10^n 

In GHCI:

> digits 1.2346 3 
1.235 
> digits 1.2344 3 
1.234 
> digits 1.2345 3 
1.234 

Das letzte Beispiel zeigt, dass Haskell bankübliche Rundung standardmäßig verwendet, so dass es nicht ganz entsprechen Ihre spec - aber vielleicht ist es in der Nähe genug, um trotzdem nützlich zu sein. Es ist einfach, andere Rundungsvarianten zu implementieren (oder sie auf Hackage zu finden), wenn Sie sie wirklich brauchen.

Verwandte Themen