欧拉项目第2题Julia与Python实现异常:数值结果差异求助
欧拉项目第2题:Julia代码数值溢出问题排查
问题描述
为求解欧拉项目第2题(计算小于400万的斐波那契数列偶数项之和),分别编写了Python和Julia实现代码。Python版本输出正确结果60696,但Julia版本因数值溢出产生包含负数的斐波那契数列,最终得到错误结果-4840,需排查问题根源。
Python实现代码
import numpy as np # Function to generate the Fibonacci series def fibonacci_fun(fib_series_fun, num_terms_fun): # Initialize the first value in series first_num_fun = 1 # Append the first value to series fib_series_fun.append(first_num_fun) # Initialize the value preceeding the first number; technically always 0 but 1 in this problem num_bef_start_fun = 1 # Add the first_num to the num_bef_start value and append it next_num_fun = first_num_fun + num_bef_start_fun fib_series_fun.append(next_num_fun) # While we do not have num_terms number of elements in Fibonacci series, repeat while len(fib_series_fun) != num_terms_fun: # Add the previous 2 numbers of the series to itself new_num_fun = fib_series_fun[len(fib_series_fun)-2] + fib_series_fun[len(fib_series_fun)-1]; fib_series_fun.append(new_num_fun) return fib_series_fun # Main function def main(): # Define the number of terms in Fibonacci series num_terms = 25 # Define empty array of Int16 to store Fibonacci sereis values fib_series = [] # Run the fibonacci_fun to get the Fibonacci series fib_series = fibonacci_fun(fib_series, num_terms) print(fib_series) fib_series = np.array(fib_series) # Values less than 4 million values_less_than = fib_series[fib_series < 4000000] # Get only the even values in the Fibonacci series even_values_less_than_fib_series = values_less_than[values_less_than % 2 == 0] print(even_values_less_than_fib_series) sum_of_fib_series = sum(even_values_less_than_fib_series) print("The sum of even values in the Fibonacci series is %d.\n" %sum_of_fib_series) print("Process finished!") main()
Python输出结果
[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393] [ 2 8 34 144 610 2584 10946 46368] The sum of even values in the Fibonacci series is 60696. Process finished!
Julia实现代码
using Printf # Function to generate the Fibonacci series function fibonacci_fun(fib_series_fun, num_terms_fun) # Initialize the first value in series first_num_fun = 1 # Append the first value to series append!(fib_series_fun, first_num_fun) # Initialize the value preceeding the first number; technically always 0 but 1 in this problem num_bef_start_fun = 1 # Add the first_num to the num_bef_start value and append it next_num_fun = first_num_fun + num_bef_start_fun append!(fib_series_fun, next_num_fun) # While we do not have num_terms number of elements in Fibonacci series, repeat while length(fib_series_fun) != num_terms_fun # Add the previous 2 numbers of the series to itself new_num_fun = fib_series_fun[length(fib_series_fun)-1] + fib_series_fun[length(fib_series_fun)]; append!(fib_series_fun, new_num_fun) end return fib_series_fun end # Main function function main() # Define the number of terms in Fibonacci series num_terms = 25 # Define empty array of Int16 to store Fibonacci sereis values global fib_series = Int16[] # Run the fibonacci_fun to get the Fibonacci series fib_series = fibonacci_fun(fib_series, num_terms) println(fib_series) # Values less than 4 million values_less_than = fib_series[fib_series .< 4000000] # Get only the even values in the Fibonacci series even_values_less_than_fib_series = values_less_than[values_less_than .% 2 .== 0] println(even_values_less_than_fib_series) sum_of_fib_series = sum(even_values_less_than_fib_series) @printf("The sum of even values in the Fibonacci series is %d.\n", sum_of_fib_series) println("Process finished!") end main()
Julia输出结果
Int16[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, -19168, 9489, -9679] Int16[2, 8, 34, 144, 610, 2584, 10946, -19168] The sum of even values in the Fibonacci series is -4840. Process finished!
问题根源分析
Julia代码出现错误的核心原因是整数类型溢出:
- 代码中使用
Int16类型存储斐波那契数,而Int16的取值范围是*[-32768, 32767]*。当斐波那契数增长到28657后,下一个数46368已经超出了Int16的最大值32767。 - Julia默认对有符号整数溢出采用环绕处理(即模216运算),46368减去216(65536)后得到-19168,后续所有计算都基于错误的负数继续,最终导致求和结果错误。
- 而Python中的
int类型是任意精度整数,无论数值多大都不会出现溢出,因此能正确计算所有项。
修复方案
方案1:更换为更大的整数类型
将Julia代码中数组的类型从Int16改为Int64(Julia默认整数类型,取值范围远大于400万),或者BigInt(任意精度整数,适合超大数值)。修改后的代码片段:
# 替换原有的Int16[]定义 global fib_series = Int64[]
方案2:优化生成逻辑(更贴合题目需求)
题目要求计算小于400万的斐波那契偶数项之和,无需固定生成25项。可以修改循环条件,当生成的数值超过400万时停止,既避免溢出,又减少不必要的计算:
function fibonacci_fun(fib_series_fun) a, b = 1, 2 push!(fib_series_fun, a) push!(fib_series_fun, b) while true next = a + b if next >= 4000000 break end push!(fib_series_fun, next) a, b = b, next end return fib_series_fun end # 主函数中调用方式修改为 fib_series = fibonacci_fun(Int64[])
修复后,Julia代码将输出与Python一致的正确结果60696。
内容的提问来源于stack exchange,提问作者Shashwat Maharjan
相关产品推荐
相关产品推荐

