MIT 6.0001作业1C代码排查:两版本逻辑一致却结果迥异
排查MIT 6.0001问题集1C代码错误
问题背景
需要计算36个月内存够房子首付的最优储蓄率,允许结果与目标首付误差在100美元以内。假设条件:
- 半年加薪率(semi_annual_raise)为0.07(7%)
- 投资年回报率(annual return)为0.04(4%)
- 首付为房价的0.25(25%)
- 目标房价为100万美元
两段代码及运行结果
第一段代码(运行错误)
annual_salary=float(input("Enter your annual salary:")) semi_annual_raise=0.07 total_cost=1000000 portion_down_payment = 0.25 current_saving=0 r=0.04 low=0 high=10000 guess=(low+high)/2 numGuesses=0 while abs(portion_down_payment*total_cost-current_saving)>=100: current_saving=0 portion_saved=guess/10000 for i in range (36): current_saving+=current_saving*r/12+annual_salary/12*portion_saved if i%6==0 and i>0: annual_salary+=annual_salary*semi_annual_raise if portion_down_payment*total_cost-current_saving>0: low=guess else: high=guess guess=(low+high)/2 numGuesses+=1 if numGuesses > 1000: break if numGuesses>1000: print("It is not possible to pay the down payment in three years.") else: rate=guess/10000 print("steps in bisection search is",numGuesses,"and the best saving rate is",rate)
输入年薪150000时,结果:
It is not possible to pay the down payment in three years.
第二段代码(运行正确)
annual_salary=float(input("Enter your annual salary:")) semi_annual_raise=0.07 total_cost=1000000 portion_down_payment = 0.25 r=0.04 low=0 high=10000 guess=(low+high)/2 numGuesses=0 def current_saving(annual_salary,guess,months): portion_saved=guess/10000 saving=0 r=0.04 semi_annual_raise=0.07 for i in range (months): saving+=saving*r/12+annual_salary/12*portion_saved if i%6==0 and i>0: annual_salary+=annual_salary*semi_annual_raise return(saving) total=0 while abs(portion_down_payment*total_cost-total)>=100: total=current_saving(annual_salary,guess,36) if portion_down_payment*total_cost-total>0: low=guess else: high=guess guess=(low+high)/2 numGuesses+=1 if numGuesses > 1000: break if numGuesses>1000: print("It is not possible to pay the down payment in three years.") else: rate=guess/10000 print("steps in bisection search is",numGuesses,"and the best saving rate is",rate)
输入相同年薪时,结果:
steps in bisection search is 7 and the best saving rate is 0.44140625
错误定位
两段代码的核心差异在于年薪变量的作用域:
- 第一段代码中,
annual_salary是全局变量,每次执行while循环内的for循环时,都会对它进行加薪修改。这意味着后续的二分迭代使用的是已经涨过多次工资的数值,而非用户初始输入的年薪。随着迭代次数增加,计算出的储蓄额会远高于实际基于初始工资的数值,导致二分搜索逻辑混乱,最终错误判断为无法凑够首付。 - 第二段代码中,函数
current_saving接收的是初始的annual_salary作为参数,在函数内部修改的是局部变量,不会影响全局的初始年薪。每次二分迭代时,都是基于用户输入的原始工资重新计算储蓄额,逻辑正确。
修正后的第一段代码
annual_salary=float(input("Enter your annual salary:")) initial_salary = annual_salary # 保存初始年薪 semi_annual_raise=0.07 total_cost=1000000 portion_down_payment = 0.25 current_saving=0 r=0.04 low=0 high=10000 guess=(low+high)/2 numGuesses=0 while abs(portion_down_payment*total_cost-current_saving)>=100: current_saving=0 portion_saved=guess/10000 current_salary = initial_salary # 每次迭代都使用初始工资 for i in range (36): current_saving+=current_saving*r/12+current_salary/12*portion_saved if i%6==0 and i>0: current_salary+=current_salary*semi_annual_raise if portion_down_payment*total_cost-current_saving>0: low=guess else: high=guess guess=(low+high)/2 numGuesses+=1 if numGuesses > 1000: break if numGuesses>1000: print("It is not possible to pay the down payment in three years.") else: rate=guess/10000 print("steps in bisection search is",numGuesses,"and the best saving rate is",rate)
内容的提问来源于stack exchange,提问作者X Y
相关产品推荐
相关产品推荐

