Haskell: how can I use math functions like "logBase" to work with unbounded integers?
I'm trying to generate a list of Fibonacci numbers to compare with a list of primes (e.g.). Both lists begin at the first known fibo/prime number and end at the 10000th. The problem is: a graphical comparison (chart) is only possible when some function like "logBase 2" is applied to the fibo numbers, but "logBase" works only(?) with "Floating" numbers. Unfortunately, fibo numbers get enormous, so I think 开发者_如何学Pythonfibo numbers should be "Integer" (unbounded).
This leads to conversion problems.
Example (Double versus Integer versus Rational):
Prelude> (fromInteger 99^155 :: Double)
Infinity
Prelude> 99^155
2105984461967288122980631709715261275645844225982779394351624787177327329412781425212770617487844004735075332631944629831514476725173837569097618069672639524362255333585985536520710945968603104880488606713054412670128838036813075895861981025491395960367363513228812061706617371582639821584522415306665565665499
Prelude> logBase 2 $ fromRational (fromInteger 99^155 :: Rational)
Infinity
Therefore, the question: How can I use math functions like "logBase" to work with unbounded integers? Some hint?
How about using the mathematical properties of log - something like
{-# LANGUAGE ScopedTypeVariables #-}
logBaseRational :: forall a . (RealFloat a, Floating a) => Rational -> Rational -> a
logBaseRational k n | isInfinite (fromRational n :: a) = logBaseRational k (n/k) + 1
logBaseRational k n | isDenormalized (fromRational n :: a) = logBaseRational k (n*k) - 1
logBaseRational k n = logBase (fromRational k) (fromRational n)
Something more efficient could be done if you need to handle really large numbers, but this should do for the range you're interested in.
The use of ScopedTypeVariables
is just to ensure that the isInfinite
and isDenormalized
tests are done at the right type.
Also, isDenormalized
isn't a complete test for the bottom end of the range - what you want is to check both that (because of loss of precision issues) and also whether the converted value is 0
when the unconverted value isn't - but since this question is about large numbers only it's not important, I just threw it in to make my answer more general.
精彩评论