diff --git a/epicardium/modules/rtc.c b/epicardium/modules/rtc.c
index 630ece854da06374e18ec0cf5a747a68f241bbec..b563462dbc242194e7f931721d82fcd21d0b344e 100644
--- a/epicardium/modules/rtc.c
+++ b/epicardium/modules/rtc.c
@@ -44,6 +44,22 @@ uint64_t epic_rtc_get_milliseconds(void)
 	while (RTC_GetTime(&sec, &subsec) == E_BUSY) {
 		vTaskDelay(pdMS_TO_TICKS(4));
 	}
+
+	// Without the bias of 999 (0.24 milliseconds), this decoding function is
+	// numerically unstable:
+	//
+	// Encoding 5 milliseconds into 20 subsecs (using the encoding function in
+	// epic_rtc_set_milliseconds) and decoding it without the bias of 999 yields
+	// 4 milliseconds.
+	//
+	// The following invariants should hold when encoding / decoding from and to
+	// milliseconds / subseconds:
+	//
+	// - 0 <= encode(ms) < 4096 for 0 <= ms < 1000
+	// - decode(encode(ms)) == ms for 0 <= ms < 1000
+	// - 0 <= decode(subsec) < 1000 for 0 <= subsec < 4096
+	//
+	// These invariants were proven experimentally.
 	return (subsec * 1000ULL + 999ULL) / 4096 + sec * 1000ULL;
 }