如何在计算Pascals Triangle行时避免InexactError

时间:2017-05-15 09:01:33

标签: julia

我写了一个函数来计算一行Pascals Triangle。

function calc_row(s, prev::Int64, num::Int64, den::Int64)
    c = 1
    next_num = num
    next_den = den

    if prev > 0
        c = convert(Int64, round(prev * (num / den)))

        next_num = num - 1
        next_den = den + 1
    end

    s = push!(s, c)

    if next_num > 0
        calc_row(s, c, next_num, next_den)
    else
        s
    end
end

function row(r)
    s = []
    calc_row(s, 0, r, 1)
end

有了更大的输入,比如row(392),它会死于:

ERROR: LoadError: InexactError()
 in calc_row(::Array{Any,1}, ::Int64, ::Int64, ::Int64) at /var/tmp/148-3.julia:17
 in calc_row(::Array{Any,1}, ::Int64, ::Int64, ::Int64) at /var/tmp/148-3.julia:26 (repeats 10 times)
 in row(::Int64) at /var/tmp/148-3.julia:34
 in include_from_node1(::String) at ./loading.jl:488
 in include_from_node1(::String) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
 in process_options(::Base.JLOptions) at ./client.jl:262
 in _start() at ./client.jl:318
 in _start() at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
while loading /var/tmp/148-3.julia, in expression starting on line 37

违规行是:

c = convert(Int64, round(prev * (num / den)))

在计算三角形中的条目时,如何在使用整数时避免此错误?

1 个答案:

答案 0 :(得分:2)

基本上,问题中的代码是正确的。要做大行数BigInts更好,因为Int64不足以容纳这样的数字。此外,整数计算的浮点数是麻烦和舍入错误的根源。所以,有点修饰版本:

function calc_row(s, prev, num, den)
    c = one(den)
    next_num = num
    next_den = den
    if prev > 0
        c = (prev * num) ÷ den
        next_num = num - 1
        next_den = den + 1
    end
    s = push!(s, c)
    return next_num > 0 ? calc_row(s, c, next_num, next_den) : s
end

function row{T}(r::T)
    s = Vector{T}(0)
    calc_row(s, zero(T), r, one(T))
end

row(BigInt(392))给出了:

393-element Array{BigInt,1}:
                             1
                           392
                         76636
                       9962680
                     968870630
                   75184360888
                 4849391277276
               267409290432648
             12869072102071185
            549080409688370560
          21029779691064592448
         730306894726061301376
       23187243907552446318688
      677780975759225353930880
    18348499272339029224271680
   462382181662943536451646336
 10894880155433107077641916792
                             ⋮
 10894880155433107077641916792
   462382181662943536451646336
    18348499272339029224271680
      677780975759225353930880
       23187243907552446318688
         730306894726061301376
          21029779691064592448
            549080409688370560
             12869072102071185
               267409290432648
                 4849391277276
                   75184360888
                     968870630
                       9962680
                         76636
                           392
                             1