可能的最大计算

时间:2014-12-29 02:31:50

标签: ruby for-loop integer max

我有一种方法来计算输入数的阶乘

def fact( n )
  if (n == 0)
    1
  else
    n * fact(n-1)
  end
end

我想创建一个循环来测试此方法的最大可计算值。对于我的机器,这个数字是8734,但我发现通过反复试验。

我的想法是创建一个for / each循环并测试返回的结果是否是实数。我只想放置实际产生实际数值结果的最后一个数值。

谢谢!

2 个答案:

答案 0 :(得分:1)

我会做这样的事情:

i = 1
loop do
  begin
    fact(i)
  rescue SystemStackError
    puts "stack level too deep at: #{i}"
    break
  end

  i += 1
end

请注意,这是一个非常天真的算法,可以检查每个数字,可能需要一些时间。在一系列数字上进行某种二元搜索必须更快。

答案 1 :(得分:0)

你可以像@spickermann所建议的那样,但是没有必要搜索引发异常的fact的参数。相反,只需为任何适当大的fact(n)值(例如n)计算n = 100_000,每次调用fact时递增堆栈深度计数器,并报告其值提出SystemStackError异常时的计数器。以下代码对n的各种值执行该计算,表明n的值不重要,只要它适当大。我认为n = 100_000对于任何Ruby实现来说都是很大的,但是如果你愿意,可以把它变成一百万。

def fact( n )
  @stack_size += 1
  if (n == 0)
    1
  else
    n * fact(n-1)
  end
end

[10_000, 20_000, 50_000, 100_000, 8733, 8732].each do |n|
  print "n=#{n.to_s.ljust(6)}: "
  begin
    @stack_size = 0
    fact(n)
  rescue SystemStackError
    puts "stack level too deep at: #{@stack_size}"
  end
end

# n=10000 : stack level too deep at: 8733
# n=20000 : stack level too deep at: 8733
# n=50000 : stack level too deep at: 8733
# n=100000: stack level too deep at: 8733
# n=8733  : stack level too deep at: 8733
# n=8732  :

请注意,n => 8732时未引发异常。

最大堆栈深度是否取决于方法?当然!如果我们将fact替换为:

def fact(n)
  @stack_size += 1
  fact(n-1)
end

我们得到:

# stack level too deep at: 9356