If we have two integer numbers mm and in,
mm = 100 * millimeters
in = 2000 * inches
then the conversions between the two are
mm_to_inch(mm) = (mm * 100 ± 63) / 127
inch_to_mm(in) = (in * 127 ± 50) / 100
where ± means addition if mm or in is positive, subtraction if negative.
For display purposes, you do need to multiply in by five.
Unfortunately, inch_to_mm(mm_to_inch(mm)) == mm±1: the roundtrip is off by 0.01mm in about 21% of cases, because the mm_to_inch() conversion maps a wider range to a narrower range: more than one reading in tens of micrometers maps to the same reading in half-thousandths of an inch. This cannot be avoided, unless the inches precision is increased; and that means the final digit can be something other than 0 or 5.
If the final digit can be any even digit, i.e.
mm = 100 * millimeters
in = 5000 * inches
and you double in for display purposes, then
mm_to_inch(mm) = (mm * 250 ± 63) / 127
inch_to_mm(in) = (in * 127 ± 125) / 250
and you get a 1:1 mapping between inches and millimeters.
Since 250 / 127 = 1000 / 508 = 1/0.508, you could implement
mm_to_inch(mm) = 2*round( mm / 0.508 )
which includes the doubling for display purposes, i.e. the result is in ten-thousandths of an inch; or equivalently
mm_to_inch(mm) = round_to_even( mm / 0.254 );
i.e.
int mm_to_inch(const int mm) { return 2*round((double)mm * 250.0 / 127.0); }
or, equivalently,
int mm_to_inch(const int mm) { return 2*(int)(mm * 250 + (mm < 0 ? -63 : +63)) / 127);
or, equivalently,
int mm_to_inch(const int mm)
{
unsigned int u = (mm < 0) ? -mm : mm;
int n = 0;
// Up to 15 iterations
while (u >= 65024) {
u -= 65024; // 0b1111'1110'0000'0000 = 127 << 9
n += 256;
}
// Up to 15 iterations
while (u >= 4064) {
u -= 4064; // 0b1111'1110'0000 = 127 << 5
n += 16;
}
// Up to 15 iterations
while (u >= 254) {
u -= 254; // 0b1111'1110 = 127 << 1
n++;
}
// We now have (n = abs(mm) / 254, u = abs(mm) % 254
n *= 1000; // n = (n << 10) - (n << 3) - (n << 4);
u *= 1000; // u = (u << 10) - (u << 3) - (u << 4);
// Up to 31 iterations
while (u >= 8128) {
u -= 8128; // 0b0001'1111'1100'0000 = 127 << 6
n += 32;
}
// Up to 31 iterations
while (u >= 254) {
u -= 254; // 0b1111'1110 = 127 << 1
n++;
}
// Round to even
n += (n & 1);
return (mm < 0) ? -n : n;
}
The three mm_to_inch() functions above do produce identical results for -999999 ≤ mm ≤ +999999; I checked.
And, as I mentioned above, this is bijective: each unique mm value maps to an unique even in value, which if multiplied by 0.254 and rounded, will yield the original mm value. For half-thousandths of an inch, bijective mapping is not possible.