3

我正在尝试生成一个斐波那契数字列表以与素数列表(例如)进行比较。两个列表都从第一个已知的 fibo/素数开始,到第 10000 个结束。问题是:图形比较(图表)只有在“logBase 2”之类的函数应用于 fibo 数字时才有可能,但“logBase”仅适用于(?)与“浮动”数字。不幸的是,斐波纳奇数变得巨大,所以我认为斐波纳奇数应该是“整数”(无界)。

这会导致转换问题。

示例(Double vs Integer vs Rational):

Prelude> (fromInteger 99^155 :: Double) 
Infinity

Prelude> 99^155
2105984461967288122980631709715261275645844225982779394351624787177327329412781425212770617487844004735075332631944629831514476725173837569097618069672639524362255333585985536520710945968603104880488606713054412670128838036813075895861981025491395960367363513228812061706617371582639821584522415306665565665499

Prelude> logBase 2 $ fromRational (fromInteger 99^155 :: Rational) 
Infinity

因此,问题是:如何使用诸如“logBase”之类的数学函数来处理无界整数?一些提示?

4

1 回答 1

2

如何使用对数的数学属性 - 比如

{-# 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)

如果您需要处理非常大的数字,可以做一些更有效的事情,但这应该适用于您感兴趣的范围。

的使用ScopedTypeVariables只是为了确保isInfiniteisDenormalized测试以正确的类型完成。

此外,isDenormalized这不是对范围底端的完整测试 - 您想要检查两者(因为精度问题的损失)以及转换后的值是否是0未转换的值 - 但是因为这个问题是关于大数字的,但这并不重要,我只是把它扔进去以使我的答案更笼统。

于 2011-06-30T06:49:45.823 回答