问题:用一个输入创建一个函数。返回包含斐波那契序列(从0开始)的数组的索引,该数组的元素与函数的输入匹配。
16 │ def f(p)
17 │ fib_now = 0u64
18 │ fib_last = 0u64
19 │ fib_hold = 0u64
20 │ i = 0u64
21 │
22 │ return 0 if p == 0
23 │
24 │ loop do
25 │ if fib_now == 0
26 │ fib_last = 0
27 │ fib_now = 1
28 │ i += 1
29 │ next
30 │ end
31 │
32 │ fib_hold = fib_now
33 │
34 │ fib_now = fib_last + fib_now
35 │ fib_last = fib_hold
36 │
37 │ #puts "fib_last is: %s\tfib_now is: %s" % [fib_last, fib_now]
38 │
39 │ return fib_now if i == p
40 │
41 │ i += 1
42 │ end
43 │ end
44 │
45 │ def usage
46 │ progname = String.new(ARGV_UNSAFE.value)
47 │
48 │ STDERR.puts <<-H
49 │ #{progname} <integer>
50 │ Given Fibonacci; determine which fib value would
51 │ exist at <integer> index.
52 │ H
53 │
54 │ exit 1
55 │ end
56 │
57 │ if ARGV.empty?
58 │ usage
59 │ end
60 │
61 │ begin
62 │ puts f ARGV[0].to_i64 # maybe this is problematic?
63 │ rescue e
64 │ STDERR.puts e
65 │ usage
66 │ end
$ crystal build fib.cr
$ ./fib 45
1836311903
$ ./fib 46
Arithmetic overflow
$ ./fib.rb 460
985864329041134079854737521712801814394706432953315\
510410398508752777354792040897021902752675861
我对这个问题的解决方案绝非优雅,我在很累的时候是在凌晨2点做到的。所以我不是在寻找一个更优雅的解决方案。我很好奇的是,如果我使用大于45的输入来运行结果应用程序,那么系统将显示Arithmetic overflow
。我认为我的变量输入方式做错了。我在Ruby中运行了它,它运行得很好,所以我知道这不是硬件问题...
有人可以帮我找到我做错了什么吗?我也在挖掘。我本周刚开始与Crystal合作。这是我的第二次应用/实验。我真的很喜欢,但是我还不知道它的某些特质。
Crystal中的默认整数类型为Int32
,因此,如果不显式指定整数文字的类型,则可以得到。
特别是行
fib_last = 0
fib_now = 1
将变量转换为有效类型Int32
。要解决此问题,请确保指定这些整数的类型,因为您不需要负数,UInt64
在这里似乎最合适:
fib_last = 0u64
fib_now = 1u64
还要注意我在这里使用的文字语法。您的0.to_i64
创建一个In32
,然后再创建一个Int64
。编译器将足够聪明,可以在发行版本的编译时进行此转换,但是我认为只使用文字语法会更好。