Как сохранить миллион в более сжатом виде?

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Как сохранить миллион в более сжатом виде?

Сообщение pronto » 09.08.2016 (Вт) 11:15

Всегда пожалуйста! Лишь бы на пользу пошло :)
Если будет желание, то для тренировки и полного усвоения попробуй реализовать следующую задачу.
На входе есть число в виде текста (строка символов). Нужно каждое десятичное число записать 4-мя битами. И реализовать обратную функцию — из "упакованного" числа восстановить строку.
O, sancta simplicitas!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Как сохранить миллион в более сжатом виде?

Сообщение alibek » 09.08.2016 (Вт) 12:29

pronto писал(а):Нужно каждое десятичное число записать 4-мя битами.

Да? Тренировочная задача это raw = "0x" & dec ?
Lasciate ogni speranza, voi ch'entrate.

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Как сохранить миллион в более сжатом виде?

Сообщение pronto » 09.08.2016 (Вт) 14:28

Не это я имел в виду. Я ошибочно выразился, не число, а цифру, конечно же. Уж извиняйте...
На выходе должно получиться Long, в котором на 1 байт приходится 2 двоично-десятичные цифры. raw = "0x" & dec сделает это самое?
O, sancta simplicitas!

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Как сохранить миллион в более сжатом виде?

Сообщение pronto » 27.01.2017 (Пт) 14:57

Отвечаю сам себе: Да!
Код: Выделить всё
'Упаковка (на входе число в переменной i As Long
P& = "&H" + LTrim$(i&)

'Распаковка (на выходе текст в переменной s As String)
s$ = Hex(P&)

Есть ограничение — числа на входе не могут быть больше 99 999 999.
O, sancta simplicitas!

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Как сохранить миллион в более сжатом виде?

Сообщение Don Leno » 27.01.2017 (Пт) 15:54

котором на 1 байт приходится 2 двоично-десятичные цифры - pronto, я чет вообще запутался, объясни на примере

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Как сохранить миллион в более сжатом виде?

Сообщение pronto » 27.01.2017 (Пт) 17:58

Код: Выделить всё
Есть число A = 12345678. Оно хранится в целочисленной переменной с типом Long.
Двоичное представление этого числа вот такое:
ValueToBin(12345678) = "0000 0000 1011 1100 0110 0001 0100 1110"
Есть второе число B. Оно тоже имеет целочисленный тип.
Чтобы A преобразовать в нужный формат, достаточно преобразовать A в строку
и заодно удалить пробел спереди
B = "&H" + LTrim$(A)
В переменной В окажется число 305419896
Двоичное представление этого числа вот такое:
                 ValueToBin(305419896) = "0001 0010 0011 0100 0101 0110 0111 1000"
теперь в каждых 4-х битах B по одной цифре:  1    2    3    4    5    6    7    8

Число в переменной B имеет собcтвенное название — BCD
O, sancta simplicitas!

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Как сохранить миллион в более сжатом виде?

Сообщение Don Leno » 27.01.2017 (Пт) 22:50

Спс, pronto, теперь понятно)))

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Как сохранить миллион в более сжатом виде?

Сообщение Don Leno » 29.01.2017 (Вс) 14:13

Pronto, разве при использовании твоего примера, размер не увеличивается? В Long вроде как компактнее или я ошибаюсь?
Только правда можно хранить числа более большего размера, так?
А не мог бы ты рассказать об других системах: кодирования «2 из 5» и Уплотнённые десятичные числа
что то в вики не описано о ни подробно...
PS Спрашиваю интереса ради))))

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Как сохранить миллион в более сжатом виде?

Сообщение pronto » 29.01.2017 (Вс) 16:21

Здравствуй, Don Leno!
Да, если возвращаться к задаче о компактном хранении миллиона, то его запись в BCD займёт 4 байта (3.5 байта, если быть точным). Эту запись я тебе предложил для того, чтобы поупражняться с битами. И не важно, что это можно делать встроенными средствами языка! Важно понимание при работе с битами. В процессе написания собственной функции по «упаковке» оно бы непременно появилось или закрепилось.
К сожалению, ни BCD, ни упомянутые тобою системы кодирования не очень подходят для твоей задачи.
Представь себе непрерывную последовательность бит в количестве 96 штук. Умозрительно раздели их на группы по 32 штуки. Групп получилось 96 / 32 = 3. А теперь раздели на группы по 20 штук. Групп получилось 96 / 20 = 4.8 (тебя интересуют только целые группы, то есть 4).
Код: Выделить всё
0                                       1                                       2
0000 0000 0000 0000 0000 0000 0000 0000|0000 0000 0000 0000 0000 0000 0000 0000|0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000|0000 0000 0000 0000 0000|0000 0000 0000 0000 0000|0000 0000 0000 0000 0000|0000 0000 0000 0000
0                        1                        2                        3
0000 0000|0000 0000|0000 0000|0000 0000|0000 0000|0000 0000|0000 0000|0000 0000|0000 0000|0000 0000|0000 0000|0000 0000
0         1         2         3         4         5         6         7         8         9         10        11

Можно начать с процедуры присвоения. Известен только индекс 20-битного числа (от 0 до 3). Есть идеи, что делать дальше?
O, sancta simplicitas!

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Как сохранить миллион в более сжатом виде?

Сообщение Don Leno » 29.01.2017 (Вс) 20:06

Pronto, мне правда очень хочется понять и разобраться с этой темой!!)))
Я в общем набросал небольшой пример того, как я вижу в общем о байтах, битах и hex и тп. (см рисунок primer.jpg)
В теории мне в принципе понятно, но на практике я не понимаю что и как реализовывать(((

Теперь вопрос по задачи: Я разобрал их на группы бит и что дальше? А что нужно сделать с этими битами??? (см рисунок биты2.jpg)
Вложения
primer.jpg
Общие знания
primer.jpg (29.45 Кб) Просмотров: 9437
биты2.jpg
По задаче
биты2.jpg (35.1 Кб) Просмотров: 9437

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Как сохранить миллион в более сжатом виде?

Сообщение Don Leno » 29.01.2017 (Вс) 20:17

Если смотреть по 32 битам:
Три группы соответственно 1= 1 2 3 4, 2=5 6 7 8, 3=9 10 11 12
По 20 битам:
Групп всего четыре 1= 1 2 3а, 2= 3б 4 5, 3= 6 7 8а, 4= 8б 9 10 (а - левые четыре бита, б - правые четыре бита)

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Как сохранить миллион в более сжатом виде?

Сообщение pronto » 30.01.2017 (Пн) 10:14

Это всё распрекрасно!
Теперь к этим знаниям присоедини знание о работе логических операций (AND, OR). Попробуй с их помощью записать 20 младших бит в переменную типа Long. Задача из двух действий.
O, sancta simplicitas!

Teranas
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 224
Зарегистрирован: 13.12.2008 (Сб) 4:26
Откуда: Новосибирск

Re: Как сохранить миллион в более сжатом виде?

Сообщение Teranas » 30.01.2017 (Пн) 15:47

pronto писал(а):Это всё распрекрасно!
Теперь к этим знаниям присоедини знание о работе логических операций (AND, OR). Попробуй с их помощью записать 20 младших бит в переменную типа Long. Задача из двух действий.

Это всё распрекрасно, но этому учат в седьмом классе, если не ошибаюсь... :)
С уважением, Андрей.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Как сохранить миллион в более сжатом виде?

Сообщение Don Leno » 30.01.2017 (Пн) 22:30

Может тебя и учили, а нас нет((( Спс pronto чуть позже разберусь (аврал на работе)

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Как сохранить миллион в более сжатом виде?

Сообщение Don Leno » 31.01.2017 (Вт) 23:00

pronto, выше ты писал о "чтении битов":
Код: Выделить всё
bitpart& = (v& and 12) \ 4

(это чтение, а как записать биты???)
Вот только я не понимаю, как это работает. Ты объяснил мне про установку и снятие битов, а про чтение и запись ни-ни((( Расскажешь?
Вот тогда я думаю этими операциями и можно выполнить задание))))

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Как сохранить миллион в более сжатом виде?

Сообщение pronto » 01.02.2017 (Ср) 1:09

Установка/запись для бит делается одинаково — это одно и то же... Я дал тебе уже всё, чтобы разобраться с этой темой. Чуда просветления не произойдёт, если его очень сильно не захотеть... Пожалуйста, с подобными вопросами отныне к Гугелю...
O, sancta simplicitas!

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Как сохранить миллион в более сжатом виде?

Сообщение Don Leno » 16.02.2017 (Чт) 1:03

pronto вот набросал пример! Проверь пжлста.
Только я взял не 96 бит (как сделать переменную с 96 битами???), а 32 бита Long. Считал 10 младших бит и потом их записал.
PS Кстати всегда хотел узнать правильность что и как называется:
1 byte - один байт
2 byte - DWord - одно слово
4 byte - 2 Dword - двойное слово
Правильно ли я понимаю????

И еще для того чтобы посчитать значение для 10 бит (1023) мне пришлось на листочке возводить в степень аж 10 раз, а если мне нужно так 50 бит считать и записать то как быть???? 50 раз считать!!!!
Вложения
bit_pronto.rar
(2.47 Кб) Скачиваний: 184

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Как сохранить миллион в более сжатом виде?

Сообщение Don Leno » 16.02.2017 (Чт) 8:10

Немного опишу как написал исходник:
На первой странице поста ты описал про работу с битами. Посмотрев нашел чтение группы бит:
Код: Выделить всё
bitpart& = (v& and 12) \ 4


но не мог понять как ты это делаешь, пока не прочитал про сдвиг битов:

Чтобы сдвинуть биты вправо на N позиций, то нужно число разделить на 2^N.
Чтобы сдвинуть биты влево на N позиций, то нужно число умножить на 2^N.
Например, хочу сдвинуть биты в числе 5616 на 4 позиции вправо.
2^4 (2 в степени 4) = 16
5616 / 16 = 351


В итоге деление указаное в чтении группы бит всего лишь сдвиг вправо, а оператор And соответственно устанавливает биты:

Код: Выделить всё
v& and 12 = 0000 1100
      \ 4 = 000000 11

Надеюсь я верно разобрался...
Далее про запись группы бит.
Код: Выделить всё
v& = v& or 1 ' установлен бит под номером 0
v& = v& and (not 64) ' сбросить бит 6


Изначально я думал, что установкой бита является замена 0 на 1 и что это работает только с одним битом! Но поэксперементировав с ValueToBin убедился что это не так!

Далее для задачи требовалось считать 10 младших бит в Long (12700500)

Код: Выделить всё
C1CB54 0000 0000 1100 0001 1100 1011 0101 0100


Я понял что нужно сбросить все биты кроме 10 младших бит, но как это сделать?? Посмотрев пример сброса бита, видно было что с помощью оператора Not указывается явно какие биты нужно сбросить. Я было решил посчитать на листочке все биты (возводя их в степень) и здесь остановился - осознав сколько мне придется считать))) Тогда стало ясно что нужно просто использовать инверсию функции сброса бита:

Это сброс группы бит
Код: Выделить всё
v& = v& and (not 12) ' сбросить бит 2 и 3


Это сброс всех бит, кроме 2 и 3 бита
Код: Выделить всё
v& = v& and 12


В итоге, осталось только 10 младших бит:
Код: Выделить всё
354 0000 0000 0000 0000 0000 0011 0101 0100

Вот так и получилось решить эту задачу))))

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Как сохранить миллион в более сжатом виде?

Сообщение Don Leno » 16.02.2017 (Чт) 8:45

Решил считать из значения Long каждые 8 бит отдельно, но в итоге столкнулся с тем что мне нужно посчитать сумму степени каждого бита, что и = 32-ум возведениям в степень (0-31)! Так и быть на листочке с калькулятором расписал))) Но обнаружил такую закономерность:
Код: Выделить всё
Сумма степени группы бит = следующему биту в степени -1

В итоге для того чтобы посчитать чему равна сумма степени битов с 8-15 (средние 8 младших бит) нужно:
Код: Выделить всё
2^16-1

Верно ли предположил?

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Как сохранить миллион в более сжатом виде?

Сообщение alibek » 16.02.2017 (Чт) 9:51

Поразительный вопрос.
Примерно из разряда: я обнаружил, что сумма всех разрядов десятичного числа равна единице следующего разряда минус 1, то есть 1000-1=999.
Верно ли это?
Lasciate ogni speranza, voi ch'entrate.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Как сохранить миллион в более сжатом виде?

Сообщение Don Leno » 16.02.2017 (Чт) 10:33

Alibek, может для вас это все настолько обыденно, но если ты прочел бы ранее сообщения, то понял бы что для меня битовые операции это темный лес)))) Так что pronto мне просто помогает освоиться с ними... В свою очередь чтобы ему было понятны мои рассуждения я их и пишу)))

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Как сохранить миллион в более сжатом виде?

Сообщение Mikle » 16.02.2017 (Чт) 10:37

Don Leno писал(а):битовые операции это темный лес)))) Так что pronto мне просто помогает освоиться с ними... В свою очередь чтобы ему было понятны мои рассуждения я их и пишу)))

Всё нормально, только не пиши подряд три сообщения, если после написания, до того, как кто-то успеет ответить, тебе приходит ещё мысль - нажимай "правка" и дописывай предыдущее сообщение, не замусоривай тему.

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Как сохранить миллион в более сжатом виде?

Сообщение pronto » 16.02.2017 (Чт) 11:19

Don Leno писал(а):В итоге для того чтобы посчитать чему равна сумма степени битов с 8-15 (средние 8 младших бит) нужно:
2^16-1
Верно ли предположил?

Нет. Это получилась сумма всех бит от 0-го до 15-го. Сумму бит от 8 до 15 можно посчитать так:
Код: Выделить всё
Ubit = 15: LBit = 8
S = (2 ^ (Ubit + 1) - 1) And (Not 2 ^ LBit - 1)

А вообще, хорошо. Начинаешь мыслить в правильном направлении :cheers:
PS Don Leno, опиши каждое действие — почему действие такое, что оно делает, каков результат.
O, sancta simplicitas!

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Как сохранить миллион в более сжатом виде?

Сообщение Don Leno » 16.02.2017 (Чт) 14:30

Сначало посчитаем что получается исходя из известных переменных Ubit и Lbit (даже переменные говорят сами за себя старший и младшие биты ;) ). В итоге:

Код: Выделить всё
S=(2^(15+1)-1) and (not 2^8-1)


далее

Код: Выделить всё
S=(65535) and (not 255)


так как выражения здесь является сбросом битов (аля v& = v& and (not 64) описаного тобою выше) то, значит мы сбрасываем младшие биты 0 - 7 и в результате в переменной получаем старшие биты 8 - 15.
Так я понимаю нужно применять те же битовые операции)))

pronto, спс за твои уроки))) Мне до жути интересно с этим делом освоиться, потому как часто встречаю в коде разнообразные битовые операции, но не мог их понять)))

Применимы ли битовые операции к массивам??

И еще вопрос: как считать биты 0-3 и 8-15??

Чтобы было примерно так:
Код: Выделить всё
1111 1111 0000 1111

вот мое решение:
Код: Выделить всё
1. S=(2^16-1) And ((Not 2^8-1) And (2^4-1))

Или же?
Код: Выделить всё
2. S=((2^16-1) And (Not 2^8-1)) And (2^4-1)

что-то я по-моему совсем запутался :shock: Я иногда не понимаю как And работает(( Если в связке if..Then (проверка двух чисел) или строковых переменных, где является конкатенацией. Но вот с битами? Разве во втором примере результат не будет равен лишь младшим битам 0-3, потому как:
Это сброс всех бит, кроме 2 и 3 бита
Код: Выделить всё
v& = v& and 12

И в первом примере тот же результат??
Предполагаю здесь лучше использовать сдвиг вправо, сброс младших 4 бит, потом сдвиг влево - верно?

Немного посчитал и вот:
Код: Выделить всё
S=( ((2^16-1)/16) And (Not 2^4-1) )*16


PS Mikle, благодарю! Обязательно так и буду делать! Я вот, точно не помню, разве не здесь нельзя было править сообщение, после того как прошло более 5 минут??

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Как сохранить миллион в более сжатом виде?

Сообщение pronto » 16.02.2017 (Чт) 15:56

Описано верно.

Don Leno писал(а):Применимы ли битовые операции к массивам??


Массив — это абстракция с введением понятия индекс. Под индексом понимается группа бит. Биты в памяти, из которых состоит любой тип данных, идут последовательно и непрерывно. Таким образом, не имеет значения над какими битами совершать логические операции. Вопрос только в индексации.

Чтобы считать нужные биты нужно:
1. Сбросить все другие биты.
2. Сдвинуть биты вправо на нужное количество позиций.

PS
Don Leno писал(а):Я иногда не понимаю как And работает

К Гугелю с запросом «таблица истинности AND».
O, sancta simplicitas!

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Как сохранить миллион в более сжатом виде?

Сообщение Don Leno » 16.02.2017 (Чт) 16:53

И еще вопрос: как считать биты 0-3 и 8-15??

Код: Выделить всё
S=( ((2^16-1)/16) And (Not 2^4-1) )*16
- это правильно?

Val/16 - логический сдвиг?
Как выполнить арифметический сдвиг?
Как выполнить циклический сдвиг?

То есть можно смело брать массив, например Ar(5), и производить те же самые битовые операции.
Вопрос по индексации:
Индекс выставляется в зависимости от типа хранимых данных и размерности массива?
К примеру массив Ar(2) as Byte будет выглядить так(?):
Код: Выделить всё
     0        1         2         - индекс?
0000 0010 1110 1010 1111 0000

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Как сохранить миллион в более сжатом виде?

Сообщение pronto » 16.02.2017 (Чт) 18:02

Don Leno писал(а):И еще вопрос: как считать биты 0-3 и 8-15??
S=( ((2^16-1)/16) And (Not 2^4-1) )*16
- это правильно?

Нет. Есть такая штука как последовательность действий. Она определяется наличием скобок и приоритетом оператора (возведение в степень, умножение/деление, сложение/вычитание)
Don Leno писал(а):Val/16 - логический сдвиг?
Как выполнить арифметический сдвиг?
Как выполнить циклический сдвиг?

Сложно задать эти же вопросы Гуглю?!
Don Leno писал(а):смело брать массив

Очень абстрактная формулировка... Приведи пример смелого взятия массива и нужного тебе действа над ним.
Don Leno писал(а):К примеру массив Ar(2) as Byte будет выглядить так(?):

Почти так. Только после присвоения:
Код: Выделить всё
Ar(0) = 2
Ar(1) = 234
Ar(2) = 240
O, sancta simplicitas!

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Как сохранить миллион в более сжатом виде?

Сообщение pronto » 16.02.2017 (Чт) 18:12

Я думаю, что ты уже готов понят этот код
Код: Выделить всё
Private Data() As Long, DataExist As Boolean
Private Declare Sub GetMem4 Lib "msvbvm60" (ByVal Addr As Long, Retval As Long)
Private Declare Sub PutMem4 Lib "msvbvm60" (ByVal Addr As Long, ByVal NewVal As Long)

' для чтения
Private Const ZeroOut_00FFFFF0 As Long = &HFFFFF0
Private Const ZeroOut_000FFFFF As Long = &HFFFFF

' для записи
Private Const ZeroOut_FF00000F As Long = &HFF00000F
Private Const ZeroOut_FFF00000 As Long = &HFFF00000

ReDim Data(Int(60 * 5 / 8)) ' 60 - количество 20-битных чисел

Private Sub PutNumber_v2(ByVal NumberIdx As Long, ByVal NumberVal As Long)

Dim ByteIndex As Long, DataNumber As Long

' VarPtr(Data(0)) - указатель на начало данных
ByteIndex = VarPtr(Data(0)) + Int(NumberIdx * 5 / 2)
GetMem4 ByteIndex, DataNumber

' так совпало (числа занимают 2,5 байта!), что начало числа с чётным индексом попадает
' на начало байта, а начало числа с нечётным индексом — на середину байта
' проверка нулевого бита даёт проверку на чётность, так как он задаёт разницу
' между чётным и нечётным числом.
If NumberIdx And 1 Then
   ' начало числа приходится на середину байта
   
   ' 1. Подготовить место под новое значение путём обнуления бит 4 - 23.
   DataNumber = DataNumber And ZeroOut_FF00000F
   
   ' 2. Новое значение сдвинуть на 4 бита влево
   NumberVal = NumberVal * &H10
   '
   
Else
   ' начало числа приходится на границу байта
   
   ' Подготовить место под новое значение путём обнуления бит 0 - 19.
   DataNumber = DataNumber And ZeroOut_FFF00000
   
End If

' Объединить данные из массива с новым значением
DataNumber = DataNumber Or NumberVal

' записать новое значение в массив
PutMem4 ByteIndex, DataNumber

End Sub

Private Function GetNumber_v2(ByVal NumberIdx As Long) As Long
'Dim ByteIndex As Long

' вычисление адреса байта, на который приходится начало 20-битного числа
'ByteIndex = Int(Val(NumberIdx) * 5 / 2) ' 5 и 2 получены после сокращения 20 и 8

' чтение 4-х байт.
'GetMem4 VarPtr(Data(0)) + ByteIndex, GetNumber_v2
GetMem4 VarPtr(Data(0)) + Int(NumberIdx * 5 / 2), GetNumber_v2

If NumberIdx And 1 Then
   ' начало числа приходится на середину байта
   
   ' 1. Обнулить биты с 0-го по 3-й и с 24-го по 31-й включительно
   '    &HFFFFF0 - маска для соответсвующих бит (0000 0000 1111 1111 1111 1111 1111 0000)
   '    Именно она задаёт, какие биты оставить, а какие сбросить.
   '    Если в маске бит = 1, то в результате он остаётся.
   '    Это вытекает из таблицы истинности оператора AND (Конъюнкция)
   '    V     M   R  (V - переменная, M - маска, R - результат)
   '    0 AND 0 = 0
   '    0 AND 1 = 0
   '    1 AND 0 = 0
   '    1 AND 1 = 1
   ' 2. Сдвинуть на 4 бита вправо
   GetNumber_v2 = (GetNumber_v2 And ZeroOut_00FFFFF0) \ &H10
   
Else
   ' начало числа приходится на границу байта
   
   ' 1. Обнулить биты с 20-го по 31-й включительно
   GetNumber_v2 = GetNumber_v2 And ZeroOut_000FFFFF
   
End If

End Function
O, sancta simplicitas!

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Как сохранить миллион в более сжатом виде?

Сообщение Don Leno » 18.02.2017 (Сб) 23:01

pronto, спс, код гляну на выходных)))

Пред.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 66

    TopList