Страница 1 из 1

Алгоритм преобразования десятичного числа в...

СообщениеДобавлено: 01.02.2008 (Пт) 12:26
Antonariy
... любую систему счисления. Автор функции не я.
В примере преобразование в 218ричную.

Const chars = "0123456789!#$%&()*+,-./:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîîïðñòóôõö÷øùúûüýþÿ"

Код: Выделить всё
Debug.Print conversion(123456789, Len(chars))

Function conversion(dec As Long, system As Integer) As String
    conversion = Mid$(chars, (dec Mod system) + 1, 1)
    If dec \ system <> 0 Then conversion = conversion(dec \ system, system) & conversion
End Function

Практическое применение - с помощью этой функции бинарные данные можно упаковать для передачи через XML плотнее, чем в base64. Нужно только грамотно подобрать набор символов, чтобы парсер XML их зохавал и не подавился.

Кстати, из представленной строки нужно выкинуть амперсанд и xml не пикнет. Итого - в идеале степень компресии в три с лишним (217/64 = 3,39) раза выше, чем у base64.

СообщениеДобавлено: 01.02.2008 (Пт) 15:46
kibernetics
Antonariy
о, за такое спасибо! нужно
#i?z
а как обратно то?
Пока на ум приходит только так:
Код: Выделить всё
For i=1 For Len (convstring)
char = Mid(convstring, i, 1)
Select Case char
case "#"

case "i"

case "?"

case "z"

End select
Next

СообщениеДобавлено: 01.02.2008 (Пт) 16:17
alibek
Более интересна была бы функция преобразования из любой в любую :)
Я как-то делал, была действительно универсальной, но тормозной и плохо реализованной. Надо будет еще раз попробовать.

СообщениеДобавлено: 01.02.2008 (Пт) 16:51
Antonariy
kibernetics
Думаю над этим. Кстати там была ошибка, исправил. И как выяснилось, я таки соавтор функции :) Оригинал.

ADD:
Додумал, чуть моск не спалил.
Код: Выделить всё
Function deconversion(s As String, Optional pos As Long = 0) As Long
Dim x As Long, y As Long
    If pos < Len(s) Then
        y = Len(chars) ^ (Len(s) - pos - 1)
        x = InStr(chars, Mid$(s, pos + 1, 1)) - 1
        deconversion = x * y + deconversion(s, pos + 1)
    End If
End Function

СообщениеДобавлено: 01.02.2008 (Пт) 18:02
alibek
Overflow будет, если число больше 2 миллиардов :)
Да и рекурсия слишком глубокая.

СообщениеДобавлено: 02.02.2008 (Сб) 14:22
Antonariy
Overflow будет, если число больше 2 миллиардов
А больше Long и не надо. :)
Да и рекурсия слишком глубокая.

Это где? У первой функции для двух миллиардов глубина 4. У второй равна длине передаваемой строки. Для тех же 2х миллиардов опять 4.

СообщениеДобавлено: 02.02.2008 (Сб) 21:13
Денис
Боян! Мы с Хакером уже делали перевод именно из любой в любую примерно год назад. Вот линк.