
the latest xkcd on my internet is about a programming language that attempts to eliminate off-by-one errors via "every time an integer is stored or read, its value is adjusted up or down by a random amount between 40 and 50". The title text clarifies that this generates off-by-40-or-50 errors instead.
I'm looking a little into engaging cpython with a goal of implementing something like this.
It's maybe not the best choice
so to generate a number between 40 and 50 i suppose i'd call a _PyOS_URandom function and read 1 byte. i could keep a bit cache if i were fancy, but would likely make more sense to spend time on ensuring integer stores and loads are properly effected.
ok now we have the irritating concern that 40-50 is a range that is not an integer ration of any convenient number of bits. to do 40-50 inclusive that's a size of 11. so i guess i'd discard bytes that are outside some range ummm 256%11 == 3 so uhh so i guess i'd discard 253, 254, and 255. (253%11 == 0 which aliases 0%11 == 0). drafting function: #include <pycore_pylifecycle.h> int adjust(type * val) { unsigned uint8_t adj; int status; do { status = _PyOS_URandom(&adj, 1); if (status) { return status; } } while (adj >= 253); val ooops i need an extra bit of information to decide the sign! ok ummmmm that's 12 bits? no ... i have 11 values, and a sign, so that's 22 total values. i think? +40, -40, +50, -50; 11 on each side. there's no zero so there's no signless or shared value counted on both sides of the sign. 22 total values. i think! i can always fix it if i'm wrong and actually reach an implementation. 256%22 == 14; 242%22 == 0 so discard values >= 242 copypaste, fix constants, continue: #include <pycore_pylifecycle.h> int adjust(type * val) { unsigned uint8_t adj; int status; do { status = _PyOS_URandom(&adj, 1); if (status) { return status; } } while (adj >= 242); adj ok ummm now i have negative values to contend with ... maybe it would be more conven-- ... but maybe it's clearer for me for now to keep this value unsigned #include <pycore_pylifecycle.h> int adjust(type * val) { unsigned uint8_t rnd; int status, adj; do { status = _PyOS_URandom(&rnd, 1); if (status) { return status; } } while (rnd >= 242); adj = int(rnd % 22) - 11 hrm [--