Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Нужно исправить код

280
22 апреля 2008 года
ВуД™
326 / / 04.01.2006
Вот код из перевода из 10-й с\с в любую

Код:
Public Function Dec_in(ByVal Dec_ch As String, v As Byte) As String
Dim Mas(40) As String
Dim oct As Byte
Dim i, k As Byte
Dim str As String


oct = Int(Dec_ch Mod v)
Mas(1) = oct
i = 1
Do While Dec_ch > v - 1
Dec_ch = Int(Dec_ch / v)
oct = Int(Dec_ch Mod v)
i = i + 1
Mas(i) = oct
Loop
k = i
For i = 1 To k
If v <> 16 Then
str = str + CStr(Mas(k + 1 - i))
Else
str = str + Hex(Mas(k + 1 - i))
End If
Next i

Dec_in = str
End Function

Максимом кол-во цифр можно вести 8-9, как сделать чтобы можно было ввдить и больше?
296
22 апреля 2008 года
Virtuoso
331 / / 31.07.2005
Начал искать ответ, конечно, в смене класса переменных, но не нашёл подходящего. И начал упорно думать. Может это можно обойти встроенными силами VB, но я надумал вот такое страшное дело:
Код:
Public Function Dec_in(ByVal Dec_ch As String, v As Integer) As String
Dim Mas(40) As String
Dim oct As Byte
Dim i, k As Byte
Dim str As String
   
oct = OctMod(Dec_ch, v)
   
Mas(1) = oct
i = 1
Do While Dec_ch > v - 1
Dec_ch = Int(Dec_ch / v)
oct = OctMod(Dec_ch, v)
i = i + 1
Mas(i) = oct
Loop
k = i
For i = 1 To k
If v <> 16 Then
str = str + CStr(Mas(k + 1 - i))
Else
str = str + Hex(Mas(k + 1 - i))
End If
Next i

Dec_in = str
End Function

Private Function OctMod(ByVal Dec As String, Vv As Integer) As Byte
    Dim a As String
    Dim b As Integer
    a = Dec
    Do While a >= Vv
    b = IIf(Left(a, Len(Vv)) < Vv, Len(Vv) + 1, Len(Vv))
    a = Left(a, b) Mod Vv & Right(a, Len(a) - b)
    Loop
OctMod = Int(a)
End Function

Обрати внимание, что изменился тип "v".
Теперь сижу думаю как выполнить "Dec_ch = Int(Dec_ch / v)" так, чтобы в результате оставались простые цифры в числе. Когда найду решение, думаю можно будет переводить числа любой длинны.

Выложите скорее кто-нибудь простое решение этой проблемы, чтобы мне не надо было думать)
17K
23 апреля 2008 года
HookEst
144 / / 27.03.2008
Цитата: Virtuoso

Теперь сижу думаю как выполнить "Dec_ch = Int(Dec_ch / v)" так, чтобы в результате оставались простые цифры в числе. Когда найду решение, думаю можно будет переводить числа любой длинны.


Долго думать придется:)
Проблема в том, что когда мы пишем Dec_ch / v (или Dec_ch Mod v), то строка содержащаяся в Dec_ch, будет приводится к числовому типу. Для целых в VB максимум тип Long т.е. только в диапазоне
от -2,147,483,648 до 2,147,483,647.

2,147,483,647 - это максимально число из 10 символов которое мы сможем обработать, уже 2,147,483,648 - вызовет ошибку.

Выход только в том, чтобы использовать алгоритмы работы с "длинными числами". у меня это SDiv - реализует "деление в столбик".
не стал "исправлять код"(ИМХО, какой-то он мудренный), а сделал свой, только добавить обработку ошибок

Код:
Option Explicit
Const CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Private Sub Command1_Click()
    MsgBox Dec2Any(Text1, Text2)
End Sub

' Q = A/B , R = A%B, A, Q – длинные числа, B, R - базового типа
Sub SDiv(ByVal A As String, ByVal B As Byte, ByRef Q As String, ByRef R As Byte)
Dim oldr As Byte
Dim digitQ As Byte
Dim digitA As Byte
Dim i As Long, tmp As Long

    Q = ""
    For i = 1 To Len(A) ' идти по A, начиная от старшего разряда
        digitA = CByte(Mid(A, i, 1))
        tmp = oldr * 10 + digitA ' oldr – остаток от предыдущего деления
        ' вначале oldr=0, tmp – текущая цифра A с  учетом перенесенного остатка
        digitQ = tmp \ B  ' i-я цифра частного
        oldr = tmp Mod B ' остаток примет участие в вычислении следующей цифры частного
        If Q <> "" Or digitQ <> "0" Then Q = Q & digitQ
    Next i
    R = oldr
End Sub

Function Dec2Any(ByVal Dec As String, ByVal Base As Byte) As String
'Dim Q As String
Dim R As Byte
    If Base > Len(CHARS) Then Exit Function
'цикл пока есть что делить
    Do
    'R - остаток
    SDiv Dec, Base, Dec, R
    'записываем остаток, используя символы из CHARS
    Dec2Any = Mid(CHARS, R + 1, 1) & Dec2Any
    Loop Until Dec = ""
    'если 0 возвращаем "0"
    If Dec2Any = "" Then Dec2Any = "0"
End Function
296
23 апреля 2008 года
Virtuoso
331 / / 31.07.2005
Цитата: HookEst
Долго думать придется:)



Да я идею придумал - разбить число на числа, состоящие из максимум 9-ти цифр. Каждое число делить на V, потом в них переносить запятую на определённое количество знаков и складывать результаты. Только записывать в код это всё лень очень)

17K
23 апреля 2008 года
HookEst
144 / / 27.03.2008
Цитата:

Да я идею придумал - разбить число на числа, состоящие из максимум 9-ти цифр. Каждое число делить на V, потом в них переносить запятую на определённое количество знаков и складывать результаты. Только записывать в код это всё лень очень)


куда складывать то? в Long? в Double? в любом случае возможен или overfow или потеря точности

296
23 апреля 2008 года
Virtuoso
331 / / 31.07.2005
Да не. Складывать результаты как текстовые переменные. Имею ввиду соединять, складывая отдельно каждую цифру. В общем можно, только я и говорю, что не охота этой морокой заниматься.
17K
23 апреля 2008 года
HookEst
144 / / 27.03.2008
т.е. те же "длинные числа"...
296
23 апреля 2008 года
Virtuoso
331 / / 31.07.2005
Цитата: HookEst
т.е. те же "длинные числа"...



Ну да. Как объяснить то. Например, 982374569723645972 переводим в 16-ую систему. Разбиваем его на 982374569 и 723645972. Каждое число делим на 16. Потом передвигаем под определёнными условиями запятую вправо. Получится, например, 832746500000000 и 2873682 (это я просто по клаве бью, не искать связь :) ). Ну и делаем не 832746500000000+2873682, а также как столбиком короче и записываем результат постепенно в строковую переменную. Потом переводим в Интегер. Слава Богу в VB с этим проще в отличие от C++. Примерно так.

17K
23 апреля 2008 года
HookEst
144 / / 27.03.2008
так это и есть алгоритм деления "столбиком".
Цитата:
Потом переводим в Интегер


а это еще зачем?

296
23 апреля 2008 года
Virtuoso
331 / / 31.07.2005
Тьфу ты. Чо я тут изобретаю велосипец... Не внимательно читаю. Действительно делить в столбик да и всё! Балда. Пора отдохнуть видимо мозгам)

Интегер - ну ему так надо зачем-то.
17K
23 апреля 2008 года
HookEst
144 / / 27.03.2008
Цитата:
Интегер - ну ему так надо зачем-то


:)

а писать

Цитата:
Int(Dec_ch Mod v)


тот еще велосипец...
масло-масляное:

Цитата:

Mod Operator
Used to divide two numbers and return only the remainder.
...
Remarks
...
Usually, the data type of result is a Byte, Byte variant, Integer, Integer variant, Long, or Variant containing a Long, regardless of whether or not result is a whole number. Any fractional portion is truncated. However, if any expression is Null, result is Null. Any expression that is Empty is treated as 0

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог