Simple answer: don't.
Computers are precise, discrete, and limited. Most programming languages are no different. You either have to limit defined behavior within the bounds of what can be done with the built-in numeric types of whatever language a solution happens to be written in (with a few patches for strange edge cases), or...
Set explicit precision/accuracy limits
Like the other answers have said, I don't think there's really a clean way to set "theoretical" boundaries without opening up gaping loopholes and weird edge cases. I think you're much better off setting explicit boundaries of defined behavior. Good challenges intentionally allow some undefined behavior; if it isn't really relevant to the challenge, let it be undefined.
In general, I would suggest avoiding challenges that require numbers larger than \$2^{52}\$ unless you have a really good reason (i.e. the challenge would be significantly altered by using smaller values e.g. generating RSA keys, SHA digests, etc...). Even better, avoid requiring anything bigger than the signed 32-bit integer range \$[-2^{31}, 2^{31} - 1]\$
Rather than working around theoretical limits, my challenges usually specify a range of values that must work to be considered valid solutions. Anything outside that precision and accuracy is undefined. Make limits tight enough that almost any programming language or architecture could solve the problem without excessive effort that's not really relevant to the challenge itself- I usually aim for what fits in an int16, a float32, or 4 decimal digits since these are common denominators to almost every language/architecture made since 1990.
Addendum: I think the way you handled it in the challenge you linked is fine, but these sorts of challenges that map numbers to something should be avoided if that something has more than \$2^{52}-1\$ possible states since that encloses a common denominator of distinct integer limits.
A few examples from my challenges:
From Heavy Box Stacking
- You must support weights up to 9,999 kg, at minimum.
- You must support up to 9,999 total boxes, at minimum.
From Compound Interest... With Wizard Money
- Input and output may be in any convenient format. You must take in Knuts, Sickles, Galleons, interest rate, and time. All but interest
rate will be whole numbers. The interest rate is in increments of
0.125%.
...snip...
- Totals owed, up to 1,000 Galleons, should be accurate to within 1 Knut per year of interest when compared with arbitrary precision
calculations.
- You may round down after each year of interest or
only at the end. Reference calculations can take this into account for
accuracy checks.
From Arrays Start at \$\pi\$
- Your result must have at least two decimal points of precision, be accurate to within 0.05, and support numbers up to 100 for this precision/accuracy. (single-precision floats are more than sufficient to meet this requirement)
From Intersection Point of Two Line Segments
- A minimum of 2 decimal places (or equivalent) precision is required.
- Final results should be accurate to within 0.01 when at a scale of -100 - +100. (32-bit floats will be more than accurate enough for this purpose)
From Length of the Longest Descent
- You may assume the height map is perfectly rectangular, is nonempty, and contains only positive integers in the signed 32-bit integer range.