Скажем, число 35 превратится в 3,5×101, а число 123 - в 1,2×102.
Мы пытаемся формализовать такое преобразование. Записываем все 6 разрядов числа, даже если там нули:
000035
Изначально мы присваиваем порядок ("экспоненту") e=5. А далее, сдвигаем число влево по одному разряду, и попутно вычитаем по единичке из e, пока в старшем разряде не появится ненулевая цифра:
000350, e=4,
003500, e=3,
035000, e=2,
350000, e=1. Вот оно!
И остаётся округлить число до двух значащих разрядов, взять два старших разряда - и операция завершена.
Но есть здесь одна небольшая подлянка...
До тех пор, пока мы просто отсекаем младшие разряды - всё действительно просто. Но если применить округление до ближайшего целого, то после округления у нас может поменяться порядок (экспонента).
Скажем, 9997 сначала превратится в 9,997×103, а после округления до двух разрядов - в 10,0×103. Так что теперь мы обязаны "сдать назад", и получить ответ 1,0×104. В общем-то, конкретно "сдавать назад" необязательно: мы точно знаем, что ответом будет единичка, поскольку только "все девятки" при округлении смогут вызвать переполнение.
Всё то же самое справедливо и для двоичных чисел.
Так что перфекционизм при нахождении масштаба мог дорого обойтись (насыщение результата в нашем QuatCore работает только со знаком. Если используем адрес UAC, Unsigned ACc, биты берутся "как есть", и 65535 может вдруг превратиться в 0). Уж если решил провести округление - нужно предусмотреть случай выхода за диапазон.
Не знаю теперь, стоит ли вообще в этом месте округление делать. Это алгоритм захвата - от него требуется ровно такая точность, чтобы устойчиво войти в сопровождение. Сама по себе замена корня из суммы квадратов на взвешенную сумму Манхэттенской и Чебышевской метрики даёт нам ошибку измерения масштаба до 0,4%, а это вообще-то 260 единиц младшего разряда.
С другой стороны, я сам же писал, как важно использовать правильное округление...