Base36
|
|
ShadEx | Дата: Среда, 27.03.2013, 00:04 | Сообщение # 1 |
Лейтенант
Группа: Проверенные
Сообщений: 51
Статус: Offline
| Base36 - это способ кодирования, который применяется для чисел(или преимущественно, массивов чисел). Так как в основном такие массивы содержат беззнаковые числа, то соответственно функции обрабатывают тип Uinteger:
Код Function base36encode(number As UInteger) As String Dim alphabet As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" If number = 0 Then return "0" Dim As String res_b36 = "" While number > 0 res_b36 = Mid(alphabet, number Mod 36 + 1, 1) & res_b36 number = number \ 36 wend return res_b36 End Function
Function base36decode(ByRef base36 As String) As UInteger Dim alphabet As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" Dim As UInteger num_b36 = 0 num_b36 = InStr(1, alphabet, Right(base36, 1)) - 1 For i As integer = Len(base36) - 1 To 1 Step -1 num_b36 = num_b36 + 36 ^ (Len(base36) - i) * (InStr(1, alphabet, Mid(base36, i, 1)) - 1) Next i Return num_b36 End Function
Пример:
Код Dim As UInteger snum = 125175458 Dim As string sint36 = base36encode(snum) Print sint36 Print base36decode(slong36) sleep
|
|
| |
haav | Дата: Среда, 27.03.2013, 09:07 | Сообщение # 2 |
![haav](/avatar/00/5416-572652.jpg) Генералиссимус
Группа: Администраторы
Сообщений: 1363
Статус: Offline
| Хороший, маленький пример. Надо будет выложить на основном сайте. Спасибо.
Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
|
|
| |
electrik | Дата: Суббота, 06.04.2013, 19:31 | Сообщение # 3 |
Полковник
Группа: Друзья
Сообщений: 182
Статус: Offline
| оптимизированный код кодирования в base36. по поводу раскодирования, еще думаю.
Код Function base36encode(number As UInteger) As zstring ptr static alphabet As String * 36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" static As zString * 8 res_b36 dim res_b36Ptr as zstring ptr = @res_b36+6 *res_b36Ptr = alphabet[0] If number = 0 Then return res_b36Ptr
While number *res_b36ptr = alphabet[number mod 36] number = number \ 36 if number then res_b36Ptr -=1 wend return res_b36Ptr End Function print *base36encode(4294967295) sleep
Сообщение отредактировал electrik - Суббота, 06.04.2013, 19:34 |
|
| |
haav | Дата: Суббота, 06.04.2013, 19:56 | Сообщение # 4 |
![haav](/avatar/00/5416-572652.jpg) Генералиссимус
Группа: Администраторы
Сообщений: 1363
Статус: Offline
| Вот еще бы нормальную замену функции MOD найти. Она тоже довольно медленная.
Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
|
|
| |
electrik | Дата: Воскресенье, 07.04.2013, 04:29 | Сообщение # 5 |
Полковник
Группа: Друзья
Сообщений: 182
Статус: Offline
| очень странно, ведь используются сопроцессор команды. поглядим, может реализации на асме есть. если перегрузить оператор, ... не самый лучший способ, так как для него новая функция заводится. жаль, что во FreeBasic нет inline функций. эьто, типа, развернутая функция, что-то наподобе макроса, только красивее.
Добавлено (07.04.2013, 04:24) --------------------------------------------- поглядел asm listing, не так уж все плохо.строка типа: *res_b36ptr = alphabet[number mod 36] выглядит так: mov ebx, dword ptr [ebp+8] ' number mov ecx, 36 делитель mov eax, ebx ' делимое xor edx, edx ' обнулим edx div ecx ' делим mov eax, edx ' записываем в eax остаток из edx mov ebx, eax ' запишем в ebx eax mov eax, offset _Lt_000E ' получим смещение к началу массива alphabet add eax, ebx ' добавим к смещению полученную позицию при делении mov ebx, dword ptr [ebp-8] ' запишем в ebx указатель на буфер из [ebp-8] mov cl, byte ptr [eax]' запишем в cl байт из массива из указателя
[eax]mov byte ptr [ebx], cl ' запишем в буфер по указателю [ebx]байтДобавлено (07.04.2013, 04:29) --------------------------------------------- кстати, на форуме как то глючит поле редактирования. я пытаюсь что-то вставить в середину, а оно в начало вставляется. может моя говорилка его плохо обрабатывает.
Сообщение отредактировал electrik - Воскресенье, 07.04.2013, 04:26 |
|
| |
haav | Дата: Воскресенье, 07.04.2013, 08:04 | Сообщение # 6 |
![haav](/avatar/00/5416-572652.jpg) Генералиссимус
Группа: Администраторы
Сообщений: 1363
Статус: Offline
| Да вроде asm листинг выглядит неплохо. У меня это ощущение по поводу MOD сложилось давненько, когда по примеру Lachie Dazdarian
Я создавал счетчик:
Код Frame1 = (Frame1 Mod 2) + 1 If Player.Move = FALSE Or Frame1 = 0 Then Frame1 = 1
в своей программе, использующей графику. Так вот эта штука конкретно тормозила вывод. И я вернулся к обычному варианту, который заменял:
Код Frame1 = (Frame1 MOD 2) + 1
на:
Код Frame1 = Frame1 + 1 If Frame1 > 2 Then Frame1 = 1
С тех пор как-то на эту функцию смотрел с подозрением.
Цитата кстати, на форуме как то глючит поле редактирования. я пытаюсь что-то вставить в середину, а оно в начало вставляется. может моя говорилка его плохо обрабатывает.
Да вроде вставляет туда где расположен курсор, может действительно говорилка.
Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
|
|
| |
electrik | Дата: Воскресенье, 07.04.2013, 13:46 | Сообщение # 7 |
Полковник
Группа: Друзья
Сообщений: 182
Статус: Offline
| думаю, что операция деления, долгая. в принципе, чем меньше злых расчетов, тем быстрее работает. лучше пару условий проверки вставить, чем как-то математически извращаться. где-то у меня был справочник по асму, где про каждую команду написано, сколько тактов и т.д.
|
|
| |