Точные десятичные стоят ноль, а не в сто раз дороже
Измерено, и это опровергло мою же оценку. Я сказал «медленнее в 10–100 раз». Верно это оказалось только для произвольной точности, где цифр может стать сколько угодно.
Выбранное представление другое: целое число минорных единиц. Рубль пятьдесят — это 150. Тип другой, носитель — тот же машинный double.
Числа замера (ветка work/exact-decimal, вершина 6c408f8):
- тела функций на точном типе печатаются побайтово так же, как на обычном;
- от натуральных чисел отличаются одной строкой таблицы проверки входа, и в ней только имя типа;
- секундомер: медиана отношения на 41 чередованной паре — 0,997 на сложении, 0,990 на умножении.
Чем платим на самом деле:
- диапазон ограничен 2⁵³ минорных единиц (порядка 90 триллионов рублей в копейках), а не бесконечен;
- масштаб — часть типа: сотые и тысячные не складываются, компилятор отвергает;
- деление выводит из точного типа. Вместо него — деление с остатком: 100 копеек на троих даёт 33 каждому и 1 копейку остатка,
33·3+1 = 100точно. Проверено на 3006 парах.
Почему приём сработал. Носитель не менялся, поэтому изменение не увидели восемь целей печати, JSON, мост и побайтовая сверка. Тот же приём, каким заведены натуральные числа. Это общее правило: новый тип дешёв, если он не новый вид значения.
Связано: three-number-types, exact-in-which-base, double-has-no-laws