grade calc: use bigdecimal instead of float for calculations
Convert values to bigdecimal before computing to avoid rounding issues in certain edge cases. closes GRADE-1187 Test Plan: - specs pass Change-Id: If5140e24c28647350170f559ffe6f231ed1a6a30 Reviewed-on: https://gerrit.instructure.com/151674 Tested-by: Jenkins Reviewed-by: Keith T. Garner <kgarner@instructure.com> Reviewed-by: Jeremy Neander <jneander@instructure.com> Product-Review: Spencer Olson <solson@instructure.com> QA-Review: Spencer Olson <solson@instructure.com>
This commit is contained in:
parent
63990e024c
commit
8bbfbac5d2
|
@ -901,7 +901,7 @@ class GradeCalculator
|
|||
gs[:possible].zero? || gs[:possible].nil?
|
||||
}
|
||||
final_grade = relevant_group_sums.reduce(0) { |grade,gs|
|
||||
grade + (gs[:score].to_f / gs[:possible]) * gs[:weight]
|
||||
grade + (gs[:score].to_d / gs[:possible]) * gs[:weight].to_d
|
||||
}
|
||||
|
||||
# scale the grade up if total weights don't add up to 100%
|
||||
|
@ -912,9 +912,10 @@ class GradeCalculator
|
|||
final_grade *= 100.0 / full_weight
|
||||
end
|
||||
|
||||
rounded_grade = final_grade&.to_f.try(:round, 2)
|
||||
{
|
||||
grade: final_grade.try(:round, 2),
|
||||
total: final_grade.try(:round, 2),
|
||||
grade: rounded_grade,
|
||||
total: rounded_grade,
|
||||
dropped: dropped
|
||||
}
|
||||
else
|
||||
|
|
|
@ -478,6 +478,18 @@ describe GradeCalculator do
|
|||
expect(current_groups[@group2.id][:grade]).to eq 100
|
||||
end
|
||||
|
||||
it "calculates the grade without floating point calculation errors" do
|
||||
@course.update!(group_weighting_scheme: 'percent')
|
||||
two_groups_two_assignments(50, 200, 50, 100)
|
||||
@assignment.grade_student(@user, grade: 267.9, grader: @teacher)
|
||||
@assignment2.grade_student(@user, grade: 53.7, grader: @teacher)
|
||||
calc = GradeCalculator.new([@user.id], @course.id)
|
||||
computed_scores = calc.compute_scores.first
|
||||
# floating point calculation: 66.975 + 26.95 = 93.82499999999999 => 93.82%
|
||||
# correct calcuation: 66.975 + 26.95 = 93.825 => 93.83%
|
||||
expect(computed_scores.dig(:current, :grade)).to eq 93.83
|
||||
end
|
||||
|
||||
it "should compute a weighted grade when specified" do
|
||||
two_groups_two_assignments(50, 10, 50, 40)
|
||||
expect(@user.enrollments.first.computed_current_score).to eql(nil)
|
||||
|
|
Loading…
Reference in New Issue