diff --git a/domain/sap10_calculator/worksheet/rating.py b/domain/sap10_calculator/worksheet/rating.py index ca132479a..6ed2e73fd 100644 --- a/domain/sap10_calculator/worksheet/rating.py +++ b/domain/sap10_calculator/worksheet/rating.py @@ -20,6 +20,7 @@ Table 12 (page 191). from __future__ import annotations +from decimal import ROUND_HALF_UP, Decimal from math import log10 from typing import Final @@ -59,8 +60,14 @@ def sap_rating_integer(*, ecf: float) -> int: """SAP 10.2 §13: round the continuous SAP rating to the nearest integer and clamp to a minimum of 1 ("if the result of the calculation is less than 1 the rating should be quoted as 1"). The integer value is the - one published on the EPC.""" - return max(1, round(sap_rating(ecf=ecf))) + one published on the EPC. + + "Nearest" is half-UP, as everywhere else the spec rounds (see the mapper's + `_round_half_up_2dp`). Python's built-in `round` is half-to-EVEN and would + drop an exact x.5 to x for even x — at a band floor that publishes a whole + band low (a continuous 68.5 as SAP 68 / band D rather than 69 / band C).""" + rating: Decimal = Decimal(sap_rating(ecf=ecf)) + return max(1, int(rating.quantize(Decimal("1"), rounding=ROUND_HALF_UP))) def environmental_impact_rating(