Zaokrąglanie do określonej liczby cyfr w Haskell
Próbuję stworzyć funkcję zaokrąglania liczby zmiennoprzecinkowej do określonej długości cyfr. Do tej pory wymyśliłem to:
import Numeric;
digs :: Integral x => x -> [x] <br>
digs 0 = [] <br>
digs x = digs (x `div` 10) ++ [x `mod` 10]
roundTo x t = let d = length $ digs $ round x <br>
roundToMachine x t = (fromInteger $ round $ x * 10^^t) * 10^^(-t)
in roundToMachine x (t - d)
Używamdigs
funkcja określająca liczbę cyfr przed przecinkiem, aby zoptymalizować wartość wejściową (tzn. przenieść wszystko za przecinek, więc1.234
staje się0.1234 * 10^1
)
TheroundTo
funkcja wydaje się działać dla większości danych wejściowych, jednak dla niektórych wejść otrzymuję dziwne wyniki, np.roundTo 1.0014 4
produkuje1.0010000000000001
zamiast1.001
.
Problem w tym przykładzie wynika z obliczeń1001 * 1.0e-3
(który powraca1.0010000000000001
)
Czy jest to po prostu problem z reprezentacją liczbową Haskella, z którym muszę żyć, czy też istnieje lepszy sposób na zaokrąglenie liczby zmiennoprzecinkowej do określonej długości cyfr?