Сравнение больших чисел

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

Сравнение больших чисел

Сообщение arthur2 » 06.03.2010 (Сб) 11:44

В структуре размер файла хранится в двух полях:
Код: Выделить всё
nFileSizeHigh as long
nFileSizeLow as long
Как это дело перевести, скажем в double, чтобы сравнивать привычными больше-меньше? Или нужен какой-то другой подход?
Артур
 
   

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

Re: Сравнение больших чисел

Сообщение Хакер » 06.03.2010 (Сб) 15:45

Сравниваем Hi-части, если равны, сравниваем Low-части.

В Double я не советую переводить. Другое дело, что знаковость сравнения тебя подводит.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Re: Сравнение больших чисел

Сообщение Twister » 06.03.2010 (Сб) 16:53

А если ручками записать HiPart в старшие 32 бита double-переменной, а LowPart в младшие?
А я все практикую лечение травами...

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

Re: Сравнение больших чисел

Сообщение Хакер » 06.03.2010 (Сб) 16:55

То получим бред.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Re: Сравнение больших чисел

Сообщение Twister » 06.03.2010 (Сб) 17:18

Погоди, от меня что-то ускользнуло? Разве формат double в VB не обычные два dword'а? Ну, я мог и подзабыть нюансы, конечно, сколько уже с VB дела не имею, но вроде ничего страшного не произойдет...
А я все практикую лечение травами...

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

Re: Сравнение больших чисел

Сообщение Хакер » 06.03.2010 (Сб) 17:30

Ты меня поражаешь. Double это 64-битное FP-число, которое хранит 1 бит знаковости, 11 бит экспоненты и 52 бита мантиссы. Причём Double таков и во всех остальных языках.

Угадай, что получится, если наложить ULONGLONG-число на QWORD FP.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Re: Сравнение больших чисел

Сообщение Twister » 06.03.2010 (Сб) 17:41

Не, ты не понял. Формат double мне известен. Говоря что он равен двум dword'ам я имел ввиду размер, подумал что мог с ним напутать, ведь, к примеру, integer в VB и Delphi разные.

Я как раз-таки и хотел провести эксперимент по наложению ULONGLONG на него. Т.е. каков будет результат сравнения таких вот бредовых чисел. Хотя результат должен быть таким же бредовым, там же FPU юзается. Считай - протупил :)
А я все практикую лечение травами...

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

Re: Сравнение больших чисел

Сообщение Хакер » 06.03.2010 (Сб) 17:48

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

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Re: Сравнение больших чисел

Сообщение Twister » 06.03.2010 (Сб) 18:02

Из ЛС-переписки:
Twister писал(а):Слухай, а что у нас в VB является аналогом int64/ULONGLONG?
Будешь смеяться - не помню :)

Хакер писал(а):Ничего. Хотя, возможно Currency, а возможно комовский вариантный Decimal.

Тема, честно говоря, меня заинтересовала. Т.е. конкретно вот что: на какой vb-тип можно наложить два dword'а, чтобы переменные этого типа можно было сравнивать обычным способом?

Интересно, почему ты прихватил Currency, ведь это тоже FP-число, разве нет?
А я все практикую лечение травами...

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Re: Сравнение больших чисел

Сообщение Twister » 06.03.2010 (Сб) 18:25

Должно прокатить с типом Date, он как раз 8 байт.
А я все практикую лечение травами...

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

Re: Сравнение больших чисел

Сообщение Хакер » 06.03.2010 (Сб) 18:28

Интересно, почему ты прихватил Currency, ведь это тоже FP-число, нет?

Тоже FP, только F здесь антонимичное: Fixed вместо Floating. Именно поэтому.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Re: Сравнение больших чисел

Сообщение Twister » 06.03.2010 (Сб) 18:33

Fixed-то fixed, но знаковый бит там все же есть. Что скажешь по поводу Date? Есть VB под рукой проверить?
А я все практикую лечение травами...

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

Re: Сравнение больших чисел

Сообщение Хакер » 06.03.2010 (Сб) 18:42

Fixed-то fixed, но знаковый бит там все же есть

Есть, но там нет экспоненты, что важнее. С Date это извращенство.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Re: Сравнение больших чисел

Сообщение Twister » 06.03.2010 (Сб) 18:52

С Date это извращенство.
Конечно. :) Но это решение поставленной ТС'ом задачи. Да ты и сам частенько извращаешься с VB, заставляя его делать то, что он не умеет. Так что нормально. :)

ADD: Фишка! Если в получаемой структуре Hi и Low части идут в "правильном" порядке, то эти два члена можно сразу объявить как Date и не париться с копированием в памяти. Автору достаточно лишь использовать GetFileSizeEx, что он и делает, вроде бы.
А я все практикую лечение травами...

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Сравнение больших чисел

Сообщение arthur2 » 06.03.2010 (Сб) 19:25

Twister писал(а):А если ручками записать HiPart в старшие 32 бита double-переменной, а LowPart в младшие?

Ага, только не в дабл, а в вариант начиная с 8-го байта, а в нулевой байт записать 14

Тогда получится вариант с подтипом Decimal

Вот результаты моих экспериментов, взгляните, кому не лень :) Остались ли какие-нибудь грабли?
Код: Выделить всё
Option Explicit

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)
Public Type LARGE_INTEGER
   HighPart As Long
   LowPart  As Long
End Type

Sub Main()
Dim v, i As Integer, maxLgInt
'Сотворим самое большое число, которое поместится
'в восьмибайтное целое беззнаковое:
v = CDec(1)
maxLgInt = CDec(&HF)
For i = 1 To 15
  v = v * 16
  maxLgInt = maxLgInt + v * 15
Next

Debug.Print maxLgInt
'Выводится:
' 18446744073709551615
'проверяем инженерным калькулятором:
'FFFFFFFFFFFFFFFF = 18446744073709551615
'Как в аптеке :)

'Это у нас столько байт. Переводим в терабайты:
'18446744073709551615 Б = 16 777 216 ТБ


Dim d As Double
d = maxLgInt ' Это же число в дабле
Debug.Print CDec(d) ' переводим опять в Decimal,
                    'чтобы посмотреть, что потеряли
'Выводится:
'18446744073709600000
'Потеряли 48385 байт или 387.08 кб
'Итак, даже если наш файл будет
'в шестнадцать с половиной миллионов терабайт,
'мы ошибёмся в 387.08 кб
'Так что для обозримых файлов точности дабл вполне хватит :)

'Но если точность всё-таки понадобится...

'Посмотрим, как в варианте хранится
'наше восьмибайтное целое беззнаковое:
Dim b(15) As Byte
CopyMemory b(0), maxLgInt, 16

Stop 'смотрим содержимое b и видим: нулевой байт=14,
     'само число начиная с 8-го байта и до 15-го
     'Остальные просто нули
'Осталось написать функции перевода туда-сюда:

'ValLargeInteger будет делать из LARGE_INTEGER
'число в привычном виде

'getLargeInteger будет переводить число
'(можно числом, строкой, можно в Hex-формате)
'в тип LARGE_INTEGER


'Сотворим самодельную константу &HFFFFFFFFFFFFFFFF
Dim L As LARGE_INTEGER

L.HighPart = &HFFFFFFFF
L.LowPart = &HFFFFFFFF

Dim MAX_LARGE_INTEGER
MAX_LARGE_INTEGER = ValLargeInteger(L)

Debug.Print MAX_LARGE_INTEGER 'всё получилось :)
Stop

'Ещё один эксперемент:
'берём шестрадцатиричное число 123456789ABCDEF0
'Вызываем инженерный калькулятор и переводим в десятично:
'1311768467463790320


'А теперь нашу функцию:
L.HighPart = &H12345678
L.LowPart = &H9ABCDEF0

Debug.Print " 1311768467463790320" 'столько получилось на калькуляторе
Debug.Print ValLargeInteger(L) ' сходится :)

'А теперь - обратная функция:
L = getLargeInteger("&HFECDA9876543210")

'проверяем:
Debug.Print CDec("&HFECDA9876543210")
Debug.Print ValLargeInteger(L)
'Опять сошлось :)


End Sub

Function ValLargeInteger(L As LARGE_INTEGER) As Variant
     
    CopyMemory ValLargeInteger, 14, 1 'первый байт 14
    CopyMemory ByVal VarPtr(ValLargeInteger) + 8, L.LowPart, 4
    CopyMemory ByVal VarPtr(ValLargeInteger) + 12, L.HighPart, 4

End Function

Function getLargeInteger(ByVal ValLargeInteger As Variant) As LARGE_INTEGER

'  можно передать число строкой или числом
  ValLargeInteger = CDec(ValLargeInteger)
  If ValLargeInteger > CDec("&HFFFFFFFFFFFFFFFF") Then Err.Raise 6
  If ValLargeInteger < 0 Then Err.Raise 6
 
  CopyMemory getLargeInteger.HighPart _
     , ByVal VarPtr(ValLargeInteger) + 12, 4
  CopyMemory getLargeInteger.LowPart _
     , ByVal VarPtr(ValLargeInteger) + 8, 4

End Function

Артур
 
   

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

Re: Сравнение больших чисел

Сообщение Хакер » 06.03.2010 (Сб) 19:29

Жуть. А не проще ли побайтово сравнить?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Re: Сравнение больших чисел

Сообщение Twister » 06.03.2010 (Сб) 19:32

'Итак, даже если наш файл будет
'в шестнадцать с половиной миллионов терабайт,
'мы ошибёмся в 387.08 кб
Чтоб я так писал софт... :(
Чем мой вариант не устроил?
А я все практикую лечение травами...

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Сравнение больших чисел

Сообщение arthur2 » 06.03.2010 (Сб) 19:38

Хакер писал(а):Жуть. А не проще ли побайтово сравнить?

Не проще :) После моего преобразования числа можно сравнивать, перемножать, складывать, делить, выводить результат - и всё в совершенно привычном виде.
Ты поглядел весь код? Это же просто эксперименты. Сухой остаток:

Получить значение LARGE_INTEGER:
Код: Выделить всё
Function ValLargeInteger(L As LARGE_INTEGER) As Variant
     
    CopyMemory ValLargeInteger, 14, 1 'первый байт 14
    CopyMemory ByVal VarPtr(ValLargeInteger) + 8, L.LowPart, 4
    CopyMemory ByVal VarPtr(ValLargeInteger) + 12, L.HighPart, 4

End Function

Получить LARGE_INTEGER по значению:
Код: Выделить всё
Function getLargeInteger(ByVal ValLargeInteger As Variant) As LARGE_INTEGER

'  можно передать число строкой или числом
  ValLargeInteger = CDec(ValLargeInteger)
  If ValLargeInteger > CDec("&HFFFFFFFFFFFFFFFF") Then Err.Raise 6
  If ValLargeInteger < 0 Then Err.Raise 6

  CopyMemory getLargeInteger.HighPart _
     , ByVal VarPtr(ValLargeInteger) + 12, 4
  CopyMemory getLargeInteger.LowPart _
     , ByVal VarPtr(ValLargeInteger) + 8, 4

End Function
Артур
 
   

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

Re: Сравнение больших чисел

Сообщение Хакер » 06.03.2010 (Сб) 19:39

После моего преобразования числа можно сравнивать, перемножать, складывать, делить, выводить результат

:|

Вопрос был в сравнении.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Сравнение больших чисел

Сообщение arthur2 » 06.03.2010 (Сб) 19:42

Хакер писал(а):Вопрос был в сравнении.
Вопрос был мой :) Я помню. По пути он расширился.

Twister писал(а):Чтоб я так писал софт... :(
Чем мой вариант не устроил?

Не уловил иронии :oops:
Артур
 
   

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Re: Сравнение больших чисел

Сообщение Twister » 06.03.2010 (Сб) 19:46

Не уловил иронии
Я про комментарий о потере точности.
А я все практикую лечение травами...

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Сравнение больших чисел

Сообщение arthur2 » 06.03.2010 (Сб) 19:50

Я догадался :) Всё равно не ловлю.

Дабл - знаковый и с плавающей запятой - естественно, если в него записать максимальное беззнаковое целое в столько же байт, что-то должно потеряться
Артур
 
   

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

Re: Сравнение больших чисел

Сообщение Хакер » 06.03.2010 (Сб) 19:56

Код: Выделить всё
Public Type LARGE_INTEGER
   HighPart As Long
   LowPart  As Long
End Type

Буэ.

Код: Выделить всё
    CopyMemory ByVal VarPtr(ValLargeInteger) + 8, L.LowPart, 4
    CopyMemory ByVal VarPtr(ValLargeInteger) + 12, L.HighPart, 4

Буэ.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Сравнение больших чисел

Сообщение arthur2 » 06.03.2010 (Сб) 20:05

Тьфу ты ну ты, а я думаю, почему пришлось писать шиворот навыворот :oops:

Код: Выделить всё
Public Type LARGE_INTEGER
    LowPart  As Long
    HighPart As Long
End Type
Function ValLargeInteger(L As LARGE_INTEGER) As Variant
    CopyMemory ValLargeInteger, 14, 1 'первый байт 14
    CopyMemory ByVal VarPtr(ValLargeInteger) + 8, L, 8
End Function

Function getLargeInteger(ByVal ValLargeInteger As Variant) _
                                       As LARGE_INTEGER
'  можно передать число строкой или числом
  ValLargeInteger = CDec(ValLargeInteger)
 
  If ValLargeInteger > CDec("18446744073709551615") Then Err.Raise 6
  If ValLargeInteger < 0 Then Err.Raise 6
 
  CopyMemory getLargeInteger _
     , ByVal VarPtr(ValLargeInteger) + 8, 8

End Function

Артур
 
   

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

Re: Сравнение больших чисел

Сообщение Хакер » 06.03.2010 (Сб) 20:22

Всё равно буэ.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Сравнение больших чисел

Сообщение arthur2 » 06.03.2010 (Сб) 20:24

Ну поясни теперь
Артур
 
   

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

Re: Сравнение больших чисел

Сообщение Хакер » 06.03.2010 (Сб) 20:34

Подумай над типом константы 14.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Сравнение больших чисел

Сообщение arthur2 » 06.03.2010 (Сб) 20:51

Код: Выделить всё
    Const b14 As Byte = 14
    CopyMemory ValLargeInteger, b14, 1

Так пойдёт?
Артур
 
   

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

Re: Сравнение больших чисел

Сообщение Хакер » 06.03.2010 (Сб) 20:56

Нет. Ты что, не знаешь, что такое TDC?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Сравнение больших чисел

Сообщение arthur2 » 06.03.2010 (Сб) 20:57

Не знаю :) Что это такое?
Артур
 
   

След.

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

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

Сейчас этот форум просматривают: SemrushBot и гости: 60

    TopList