';大';Julia中的分数

';大';Julia中的分数,julia,biginteger,fractions,Julia,Biginteger,Fractions,我在解决朱莉娅的欧拉项目问题时遇到了一个小问题。我基本上编写了一个递归函数,它生成的分数的分子和分母越来越大。出于显而易见的原因,我不想发布代码,但最后几部分如下: 1180872205318713601//835002744095575440 2850877693509864481//2015874949414289041 6882627592338442563//4866752642924153522 这时我得到了一个溢出错误(),大概是因为分子和/或分母现在超过了19位。在Julia中是

我在解决朱莉娅的欧拉项目问题时遇到了一个小问题。我基本上编写了一个递归函数,它生成的分数的分子和分母越来越大。出于显而易见的原因,我不想发布代码,但最后几部分如下:

1180872205318713601//835002744095575440
2850877693509864481//2015874949414289041
6882627592338442563//4866752642924153522
这时我得到了一个溢出错误(),大概是因为分子和/或分母现在超过了19位。在Julia中是否有处理“大”分数的方法(即那些具有BigInt类型的分子和分母)

增编:

好的,我已经简化了代码并对其进行了一些伪装。如果有人想涉过650个Project Euler问题,试图找出哪个问题,祝他们好运——可能会有大约200个更好的解决方案

function series(limit::Int64, i::Int64=1, n::Rational{Int64}=1//1)
    while i <= limit
        n = 1 + 1//(1 + 2n)
        println(n)
        return series(limit, i + 1, n)
    end
end

series(50)
函数系列(limit::Int64,i::Int64=1,n::Rational{Int64}=1//1)

而iJulia默认使用机器整数。有关此问题的更多信息,请参阅常见问题解答:

简言之:在任何现代CPU上,最有效的整数运算都涉及到对固定位数的计算。在你的机器上,这是64位

julia> 9223372036854775805 + 1
9223372036854775806

julia> 9223372036854775805 + 2
9223372036854775807

julia> 9223372036854775805 + 3
-9223372036854775808
哇!刚才发生了什么事!?那绝对是错误的!如果你看一下这些数字是如何用二进制表示的,那就更明显了:

julia> bitstring(9223372036854775805 + 1)
"0111111111111111111111111111111111111111111111111111111111111110"

julia> bitstring(9223372036854775805 + 2)
"0111111111111111111111111111111111111111111111111111111111111111"

julia> bitstring(9223372036854775805 + 3)
"1000000000000000000000000000000000000000000000000000000000000000"
所以你可以看到63位“耗尽了空间”并翻转过来——第64位被称为“符号位”,表示一个负数

当您看到像这样的溢出时,有两种可能的解决方案:您可以使用“检查的算术”——就像rational代码一样——确保您不会默默地遇到这个问题:

julia> Base.Checked.checked_add(9223372036854775805, 3)
ERROR: OverflowError: 9223372036854775805 + 3 overflowed for type Int64
或者您可以使用更大的整数类型,如无界的
BigInt

julia> big(9223372036854775805) + 3
9223372036854775808
因此,这里一个简单的修复方法是删除类型注释,并根据
限制动态选择整数类型:

function series(limit, i=one(limit), n=one(limit)//one(limit))
    while i <= limit
        n = 1 + 1//(1 + 2n)
        println(n)
        return series(limit, i + 1, n)
    end
end

julia> series(big(50))
#…
1186364911176312505629042874//926285732032534439103474303
4225301286417693889465034354//3299015554385159450361560051
函数系列(极限,i=1(极限),n=1(极限)//1(极限))
而我系列(大(50))
#…
1186364911176312505629042874//926285732032534439103474303
4225301286417693889465034354//3299015554385159450361560051

Julia默认使用机器整数。有关此问题的更多信息,请参阅常见问题解答:

简言之:在任何现代CPU上,最有效的整数运算都涉及到对固定位数的计算。在你的机器上,这是64位

julia> 9223372036854775805 + 1
9223372036854775806

julia> 9223372036854775805 + 2
9223372036854775807

julia> 9223372036854775805 + 3
-9223372036854775808
哇!刚才发生了什么事!?那绝对是错误的!如果你看一下这些数字是如何用二进制表示的,那就更明显了:

julia> bitstring(9223372036854775805 + 1)
"0111111111111111111111111111111111111111111111111111111111111110"

julia> bitstring(9223372036854775805 + 2)
"0111111111111111111111111111111111111111111111111111111111111111"

julia> bitstring(9223372036854775805 + 3)
"1000000000000000000000000000000000000000000000000000000000000000"
所以你可以看到63位“耗尽了空间”并翻转过来——第64位被称为“符号位”,表示一个负数

当您看到像这样的溢出时,有两种可能的解决方案:您可以使用“检查的算术”——就像rational代码一样——确保您不会默默地遇到这个问题:

julia> Base.Checked.checked_add(9223372036854775805, 3)
ERROR: OverflowError: 9223372036854775805 + 3 overflowed for type Int64
或者您可以使用更大的整数类型,如无界的
BigInt

julia> big(9223372036854775805) + 3
9223372036854775808
因此,这里一个简单的修复方法是删除类型注释,并根据
限制动态选择整数类型:

function series(limit, i=one(limit), n=one(limit)//one(limit))
    while i <= limit
        n = 1 + 1//(1 + 2n)
        println(n)
        return series(limit, i + 1, n)
    end
end

julia> series(big(50))
#…
1186364911176312505629042874//926285732032534439103474303
4225301286417693889465034354//3299015554385159450361560051
函数系列(极限,i=1(极限),n=1(极限)//1(极限))
而我系列(大(50))
#…
1186364911176312505629042874//926285732032534439103474303
4225301286417693889465034354//3299015554385159450361560051

递归函数是否有退出条件?如果不是,溢出将是由于函数永远继续…如果Julia为此抛出一个溢出错误就好了。如果没有更多关于代码本身的信息,这并不难说。如果显式使用
big
函数或
BigInt
,则不应出现溢出错误@BillBell:由于溢出在未减数的分数中非常常见,Rational代码使用检查算法。@MattB:谢谢,我没有尝试过。顺便说一句,你可能不需要太担心发布Project Euler解决方案-有很多博客和github项目以及其他已经有解决方案的地方。如果有人决定为复选标记复制粘贴解决方案,这是一项毫无意义的任务,那么无论如何,他们都有多个现有的代码源。递归函数有退出条件吗?如果不是,溢出将是由于函数永远继续…如果Julia为此抛出一个溢出错误就好了。如果没有更多关于代码本身的信息,这并不难说。如果显式使用
big
函数或
BigInt
,则不应出现溢出错误@BillBell:由于溢出在未减数的分数中非常常见,Rational代码使用检查算法。@MattB:谢谢,我没有尝试过。顺便说一句,你可能不需要太担心发布Project Euler解决方案-有很多博客和github项目以及其他已经有解决方案的地方。如果有人决定为复选标记复制粘贴解决方案,这是一项毫无意义的任务,那么不管怎样,他们已经有了多个此类代码的源代码。感谢@MattB提供的非常详细的解释——其中一些我知道,有些我不知道。如果我用我的大脑,我会意识到我可以用Rational{BigInt}而不是Rational{Int64}。我从来没有使用过literal one()–或zero()–函数,因此这增加了我的知识基础。感谢@MattB提供的非常详细的解释,其中一些我知道,一些我不知道。如果我用我的大脑,我会意识到我可以用Rational{BigInt}而不是Rational{Int64}。我从来没有使用过literal one()–或zero()–函数,因此这增加了我的知识基础。