Decimal (Variant) в Hex

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

Decimal (Variant) в Hex

Сообщение uhm » 22.05.2008 (Чт) 13:54

Всем привет! Пытаюсь решить следующую проблему: есть десятичное число, которое укладывается в пределы Decimal (но не Currency). Нужно перевести его в шестнадцатиричное представление. Hex(), естественно, не справляется; но и при попытке использовать стандартный "школьный" алгоритм практически на каждом шагу вылезает overflow. Напрямую с памятью работать не умею :oops: Подскажите, что сделать - вроде, задачка должна быть простой...
Быть... или не быть. Вот. В чём вопрос?

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

Сообщение alibek » 22.05.2008 (Чт) 14:12

А CopyMemory его в байтовый массив?
Потом можно будет уже и школьные алгоритмы задействовать.
Lasciate ogni speranza, voi ch'entrate.

uhm
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1597
Зарегистрирован: 02.12.2004 (Чт) 15:21

Сообщение uhm » 22.05.2008 (Чт) 14:43

Можно работающий пример с кодом попросить? Я по-прежнему не очень понимаю принципы работы с памятью, особенно там, где задействован Variant, а мои эксперименты уже один раз привели к перезагрузке VB :)
Быть... или не быть. Вот. В чём вопрос?

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 22.05.2008 (Чт) 15:00

Код: Выделить всё
Dim arr() as Byte
Dim x As Double

x=123.567
Redim arr(0 to len(x)-1)
CopyMemory arr(0), x, len(x)-1

Знал бы ты сколько раз падал VB от моих экпериментов...
Лучший способ понять что-то самому — объяснить это другому.

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

Сообщение alibek » 22.05.2008 (Чт) 15:04

Double то причем?
У uhm тип Variant/Decimal. Я даже не помню, какой у него размер, не то 16 байт, не то 80.
Lasciate ogni speranza, voi ch'entrate.

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 22.05.2008 (Чт) 15:07

Перепутал :oops:
Лучший способ понять что-то самому — объяснить это другому.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 22.05.2008 (Чт) 15:12

uhm
Decimal способен хранить дробные числа. Как ты их собрался преобразовывать в 16-ричноую форму? 7h.9f ?

Или тебе нужен хекс-дамп данных, хранищихся в Decimal-Variant переменной?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение alibek » 22.05.2008 (Чт) 15:14

Обыкновенно, в шестнадцатиричной форме прекрасно можно хранить и дробные числа.
В принципе, код Antonariy (если заменить декларации на Variant, а присвоение на CDec) вполне можно использовать. Но возможно в CopyMemory надо еще и смещение указывать от VarPtr.
Lasciate ogni speranza, voi ch'entrate.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 22.05.2008 (Чт) 15:35

alibek
Как будет в 16-ричной форме выглядить число 147,13?

В принципе, код Antonariy (если заменить декларации на Variant, а присвоение на CDec) вполне можно использовать. Но возможно в CopyMemory надо еще и смещение указывать от VarPtr.

Угу, надо прибавить 4, чтобы получить адрес 12-байтного Decimal-а. Но таким образом можно получить хекс-дамп переменной, а не 16-ричное представление её значения.
Согласен?

Т.к. автор не уточнил, хекс-представление чего: значения или данных ему нужно, я и задал уточняющий вопрос.

А они отличаются. Для decimal-а хоть не сильно, а вот для float/double'ов - это абсолютно разные вещи.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

uhm
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1597
Зарегистрирован: 02.12.2004 (Чт) 15:21

Сообщение uhm » 22.05.2008 (Чт) 15:53

У меня изначально есть целое число, которое лежит в пределах диапазона Decimal для целых чисел. Мне нужно представление именно этого числа, а не дампа, но дробных чисел быть не может по определению. Щас проведу еще один эксперимент, вроде, уже все понятно...
Быть... или не быть. Вот. В чём вопрос?

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

Сообщение alibek » 22.05.2008 (Чт) 16:00

Хакер писал(а):Как будет в 16-ричной форме выглядить число 147,13?

Неужели ты этого не знаешь?
Будет ~0x93.21. Более точные знаки считать лень.
Lasciate ogni speranza, voi ch'entrate.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 22.05.2008 (Чт) 16:22

Неужели ты этого не знаешь?

Не угадал. Я знаю ещё десяток способов представить дробные числа ввиде хекса. Я спрашивал, какой способ из множества возможных имеется в виду.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

uhm
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1597
Зарегистрирован: 02.12.2004 (Чт) 15:21

Сообщение uhm » 22.05.2008 (Чт) 16:34

Код: Выделить всё
Sub test()
    Dim n As Variant, arr() As Byte
    ReDim arr(0 To 11)
    n = CDec("79228162514264337593543950334")
    Debug.Print n
    CopyMemory arr(0), ByVal VarPtr(n) + 4, 12
    For i = 0 To 11
        Debug.Print IIf(Len(Hex(arr(i))) = 1, "0", "") & Hex(arr(i)) & " ";
    Next i
   
    Debug.Print
    Debug.Print
End Sub


Все, вроде, получилось, один только момент смущает - в получившемся массиве байты идут в таком порядке по старшинству: 4 3 2 1 12 11 10 9 8 7 6 5. Это нормально? :)
Быть... или не быть. Вот. В чём вопрос?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 22.05.2008 (Чт) 17:12

Это нормально. Но мне твой вариант с CopyMemory и массивом из 12 байт и склеиванием 12 строчек жутко не нравится.

Я бы сделал так:

Код: Выделить всё
Function HexFromDec(ByVal DecimalVariant As Variant) As String
    Dim buffer(0 To 2) As Long

    GetMem8 VarPtr(DecimalVariant) + 4, VarPtr(buffer(0))
    GetMem4 VarPtr(DecimalVariant) + 12, VarPtr(buffer(2))

    HexFromDec = Right$("00000000" + Hex$(buffer(0)), 8) + Right$("00000000" + Hex$(buffer(2)), 8) + Right$("00000000" + Hex$(buffer(1)), 8)
End Function


и тестим:

Код: Выделить всё
Public Sub test()
    Debug.Print "                       1 = "; HexFromDec(CDec("1"))
    Debug.Print "                     222 = "; HexFromDec(CDec("222"))
    Debug.Print "                44444444 = "; HexFromDec(CDec("44444444"))
    Debug.Print "             55555555555 = "; HexFromDec(CDec("55555555555"))
    Debug.Print "          66666666666666 = "; HexFromDec(CDec("66666666666666"))
    Debug.Print "     7777777777777777777 = "; HexFromDec(CDec("7777777777777777777"))
    Debug.Print "888888888888888888888888 = "; HexFromDec(CDec("888888888888888888888888"))
       
End Sub


результат:
Код: Выделить всё
                       1 = 000000000000000000000001
                     222 = 0000000000000000000000DE
                44444444 = 000000000000000002A62B1C
             55555555555 = 000000000000000CEF5E80E3
          66666666666666 = 0000000000003CA20AFC2AAA
     7777777777777777777 = 000000006BF037AE325F1C71
888888888888888888888888 = 0000BC3AC3627D4500E38E38
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение alibek » 22.05.2008 (Чт) 23:22

Хакер писал(а):Я знаю ещё десяток способов представить дробные числа ввиде хекса.

Правда?
Lasciate ogni speranza, voi ch'entrate.


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

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

Сейчас этот форум просматривают: Google-бот, SemrushBot и гости: 22

    TopList