Here is an answer that explains all apparent issues with arithmetic, e.g. the "off by 1" issue, or ghosts of additive modifiers.
The exact conversion factor of tiles/mobility is 0.666. This differs from the intended factor of 1/1.5 (or 2/3), which equals 0.666(6) in decimal, with an infinite number of trailing 6's. Since the game cannot process infinite precision numbers, it truncates it to 0.666, with 3 or more trailing 6's. Because of this, we now have 1/0.666 or 1.5015 mobility points per tile.
For example, with mobility 12 we have:
blue move: 12 * 0.666 = 12/1.5015 = 7.99 => round_down(7.99) = 7 tiles
yellow dash: 12 * 0.666 * 2 = 15.98 => round_down(15.98) = 15 tiles
So we get the actual 7/15 tile movement instead of the intended 8/16 tiles for mobility value of 12.
I tested all movements (single/double for straight and diagonal) for all mobility values between 3-30, and have confirmed that the factor of 0.666 correctly predicts 100% of the cases with the assumption that fractional number of tiles are always rounded down.
I've updated the ufopaedia.org page on Movement, and said more about this in the discussion page
This conversion also works for the range and radius of throwables (e.g. grenades). For example, an AP grenade has a blast radius of 5.6 mobility, which equals 5.6 * 0.666 = 3.73 straight tiles, which rounds down to a 3 tiles, and also 5.6*0.666/1.414 = 2.6 diagonal tiles which rounds down to 2 diag tiles.