You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
person_household_id and person_benunit_id are stored as float32, which rounds large identifiers #2267
person_household_id and person_benunit_id are declared with value_type = float (policyengine_uk/variables/household/demographic/), so the simulation stores them as 32-bit floats. Those hold integers exactly only up to 2**24 (16,777,216). Larger identifiers read back rounded, and different households become indistinguishable.
In a full-size UK dataset I checked, household identifiers reach about 900 million: its 535,080 distinct household identifiers are 76,551 distinct values as float32, and its 618,980 benefit unit identifiers are 544,894.
What is and is not affected
Not affected: the entity structure. build_from_ids takes memberships from the dataset tables, and the populations (ids, members_entity_id) are exact. I found no formula that reads either variable.
Affected: anything that reads the stored values. That includes calculate("person_household_id"), exports such as to_input_dataframe(), UKSingleYearDataset.from_simulation (which writes the calculated values into the person table), and any rebuild from those values. policyengine-core's subsample rebuilds that way, which is one reason Give UK simulations a working subsample #2265 gives the UK its own subsample that reads the populations instead.
Options
Declare both variables int, like household_id, benunit_id and person_id. They are then stored as 32-bit integers, which are exact up to 2**31 − 1 (about 2.1 billion). Check how datasets that store these columns as floats load, and what the metadata API reports for the type.
Keep the type and document that the stored values are approximate, with a helper that returns exact memberships from the populations.
Activity