Skip to content

Carer's Allowance: a penny a week over the 2020-21 to 2024-25 earnings limits counts as within the limit #2541

Open

Description

@MaxGhenis

is_gainfully_employed_for_carers_allowance floors the weekly pence in float32, the dtype the model stores carers_allowance_earnings in. At these magnitudes the formula's + 1e-6 tolerance does nothing: float32 spacing near 20,400 is 0.001953125, so np.float32(20400.0) + 1e-6 == np.float32(20400.0). So when weekly earnings are within about 0.002 pence of a boundary, float32 rounding decides the outcome, not the regulation. That is the case the formula's comment says the tolerance guards against.

Effect

A carer whose earnings equal pay (no tax or NI), in England, caring 40 hours, on main at c6715d4. The pay amounts are exactly a penny a week over each year's limit (52 × limit + £0.52):

year limit (£/wk) pay (£/yr) weekly model gainfully employed CA paid
2016–2019 110, 116, 120, 123 52L + 0.52 L + £0.01 yes nil (correct)
2020 128 6,656.52 £128.01 no £3,497.00 (should be nil)
2021 128 6,656.52 £128.01 no £3,515.20 (should be nil)
2022 132 6,864.52 £132.01 no £3,624.40 (should be nil)
2023 139 7,228.52 £139.01 no £3,991.00 (should be nil)
2024 151 7,852.52 £151.01 no £4,258.80 (should be nil)
2025 196 10,192.52 £196.01 yes nil (correct)
2026 204 10,608.52 £204.01 yes nil (correct)

An exhaustive check confirms it. Over every whole-pence annual amount within £2 a week of each limit in earnings_limit.yaml, the float32 formula disagrees with exact arithmetic on exactly these four limits (128, 132, 139 and 151), each at 52L + £0.52.

The 2026 case is right only because rounding happens to go up. £10,608.52 is stored as 10,608.51953125, which in exact arithmetic is 20,400.9991 pence a week (£204.00). Float32 rounds that to 20,401. The other direction fails too: an input of £10,608.5195, which is £204.0099904 a week and so £204.00 under reg. 5, stores as the same value and is treated as over the limit.

Suggested direction

Count pence in a way that doesn't depend on float32 rounding. For example, round annual earnings to whole pence in float64 and compare floor(pence / 52) > limit × 100. Add a test of 52L + £0.51 and 52L + £0.52 for every limit in the parameter file. The test-side counterpart, which mirrors the current float32 formula, is #2532 / #2534. If the formula changes, update _over_limit in test_carers_allowance_earnings_limit_properties.py and over_limit in test_carers_allowance_pension_contribution_deduction_rate_properties.py with it.

The GPT-6.1 Sol review of #2534 raised the float32 and + 1e-6 problem and the 2026 case. The 2020–2024 cases came from an exhaustive check of every limit, confirmed by the model runs above and again by the re-review of #2534.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions