FreeBasic
Главная
Вход
Регистрация
Пятница, 29.03.2024, 11:31Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Freebasic » Исходники » Base36
Base36
ShadExДата: Среда, 27.03.2013, 00:04 | Сообщение # 1
Лейтенант
Группа: Проверенные
Сообщений: 51
Репутация: 1
Статус: 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
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Хороший, маленький пример. Надо будет выложить на основном сайте. Спасибо.

Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
electrikДата: Суббота, 06.04.2013, 19:31 | Сообщение # 3
Полковник
Группа: Друзья
Сообщений: 180
Репутация: 3
Статус: 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
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Вот еще бы нормальную замену функции MOD найти. Она тоже довольно медленная.

Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
electrikДата: Воскресенье, 07.04.2013, 04:29 | Сообщение # 5
Полковник
Группа: Друзья
Сообщений: 180
Репутация: 3
Статус: 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
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: 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
Полковник
Группа: Друзья
Сообщений: 180
Репутация: 3
Статус: Offline
думаю, что операция деления, долгая. в принципе, чем меньше злых расчетов, тем быстрее работает. лучше пару условий проверки вставить, чем как-то математически извращаться. где-то у меня был справочник по асму, где про каждую команду написано, сколько тактов и т.д.
 
Форум » Freebasic » Исходники » Base36
  • Страница 1 из 1
  • 1
Поиск: