Нужда вынудила придумать
метод хранения больших величин в малом пространстве....
Делал гирлянду на тини13, в ней для задания задержки переключения шагов требуются числа от 4 до... примерно 1000, чтобы занимать поменьше места я при хранении занимал 1 байт и делал распаковку по формуле вида Y=(X+1)*4;
такое хранение занимало 8 бит и позволяло получить на выходе значения от 4 до 1028 (с шагом 4 во всём диапазоне)
меня это не очень устраивало, т.к. скорость - величина обратно пропорциональная задержке меняется очень нелинейно - в начале быстро, а затем вообще незаметно.
Спойлер
для сравнения методов я взял те-же 5 бит хранения или числа 0-31 - диапазон удручает, всего до 128...
на первом же шаге скорость падает в 2 раза! а дальше меньше, если продолжить этот ряд, то вид будет ещё печальнейТогда решил прибегнуть к методу записи чисел с плавающей точкой, именуемому в народе Float
только для тини его немного оптимизировал... сделал мини, а даже точнее
микроФлоат:
запись числа производится 2 кусками: в младших 2х битах само число, в трех старших - степень числа 2, на которое надо умножить.
- Код:
X&=0x1F; // обрезка старших битов - в них у меня теперь другая информация хранится
Y=(X&0x03)+4;
X>>=2;
Y<<=X;
Так всего в 5 битах хранятся значения от 4 до 896, и распределение чисел гораздо удобнее для настройки скорости.
Спойлер
Ну, тоже не идеально, но уже гораздо интереснее (а ровнее тут итак не получить.)
а главное - код получился подъёмным даже для мелкой тини!_____
Минифлоат4x4 - занимая 4 бита под число и 4 под множитель позволяет хранить в 1 байте целые числа от 0 до 507904.
Код распаковки:
- Код:
#define A 4
Y=X&(~((-1)<<(A)));
X>>=A;
if (X>0) // этот приём позволяет хранить числа от 0.
{
Y+=(1<<(A+1));
X--;
};
Y<<=X;
Минифлоат5x3 - занимая 5 бита под число и 3 под множитель позволяет хранить в 1 байте целые числа от 0 до 4032.
Минифлоат3x5 - занимая 3 бита под число и 5 под множитель позволяет хранить в 1 байте целые числа от 0 до 16 106 127 360. (но с бОльшим шагом)
общий вид максимального хранимого числа для переменной минифлоат(AxB) при распаковке предложенным методом будет:
Y=((2^(A+1))-1)*2^((2^B)-2).
- Вложения
-
- 2022-12-26_11-55-52.png
- (37.61 KiB) Скачиваний: 112
-
- 2022-12-26_11-56-37.png
- (35.11 KiB) Скачиваний: 98